Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1d1216d
Fix the order of Multiple Xform
junchaoxia Oct 8, 2020
be1b08e
Add unit tests of preprocess pipeline for issue #234
junchaoxia Oct 8, 2020
f011dc5
Improve Multiply Xform
junchaoxia Oct 23, 2020
d5b616e
Merge branch 'develop' into preprocess_test and solve conflicts
junchaoxia Oct 26, 2020
d2fa582
Solve conflict due to renamed parameters for unique filters
junchaoxia Oct 26, 2020
a9ee112
Simplify unit test for invert_contrast
junchaoxia Oct 26, 2020
2627ef0
Use ArraySourceImage to initialize simulation object with negative im…
junchaoxia Oct 28, 2020
db0d4ad
Remove noise from unit test of downsample
junchaoxia Oct 29, 2020
ef13a52
Use smooth Gaussian density for unit test of downsample
junchaoxia Nov 2, 2020
67b01a4
Merge branch 'develop' into preprocess_test
junchaoxia Nov 11, 2020
161c5a5
Rum commands to improve format
junchaoxia Nov 11, 2020
4ab0da7
Resolve conflict with ScaledFilter
junchaoxia Nov 11, 2020
999145c
Use non-whiting filter for initializing images
junchaoxia Nov 19, 2020
db5bf5f
Merge branch 'develop' into preprocess_test and solve conflict
junchaoxia Nov 23, 2020
5f11263
Solve the remain conflicts with develop
junchaoxia Nov 23, 2020
85dbb11
Merge branch 'develop' into preprocess_test
junchaoxia Nov 24, 2020
d18f367
Merge branch 'develop' into preprocess_test
junchaoxia Nov 25, 2020
77bfbe8
Merge branch 'develop' into preprocess_test
junchaoxia Dec 1, 2020
e6bb24a
Remove PowerFilter and use AnisotropicNoiseEstimator
junchaoxia Dec 1, 2020
2f6e363
Add downsample check for grid points
junchaoxia Dec 1, 2020
20d42ef
Add dtype and atol for tolerance
junchaoxia Dec 2, 2020
934eb94
Scale cummulated norm by image size to remove size dependency
junchaoxia Dec 4, 2020
733aca1
Merge branch 'develop' into preprocess_test
junchaoxia Dec 14, 2020
beaea3c
Use anorm to normalize each image instead of whole stack
junchaoxia Dec 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/aspire/image/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ def __mul__(self, other):

return Image(self.data * other)

def __neg__(self):
return Image(-self.data)

def sqrt(self):
return np.sqrt(self.data)

Expand Down
3 changes: 0 additions & 3 deletions src/aspire/operators/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,6 @@ def __repr__(self):
def _evaluate(self, omega):
return self.value * np.ones_like(omega)

def scale(self, c):
pass


class ZeroFilter(ScalarFilter):
def __init__(self, dim=None):
Expand Down
137 changes: 137 additions & 0 deletions tests/test_preprocess_pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import os.path
from unittest import TestCase

import numpy as np

from aspire.noise import AnisotropicNoiseEstimator
from aspire.operators.filters import FunctionFilter, RadialCTFFilter, ScalarFilter
from aspire.source import ArrayImageSource
from aspire.source.simulation import Simulation
from aspire.utils import utest_tolerance
from aspire.utils.coor_trans import grid_2d, grid_3d
from aspire.utils.matrix import anorm
from aspire.volume import Volume

DATA_DIR = os.path.join(os.path.dirname(__file__), "saved_test_data")


class PreprocessPLTestCase(TestCase):
def setUp(self):

self.L = 64
self.n = 128
self.dtype = np.float32
self.noise_filter = FunctionFilter(lambda x, y: np.exp(-(x ** 2 + y ** 2) / 2))

self.sim = Simulation(
L=self.L,
n=self.n,
unique_filters=[
RadialCTFFilter(defocus=d) for d in np.linspace(1.5e4, 2.5e4, 7)
],
noise_filter=self.noise_filter,
dtype=self.dtype,
)
self.imgs_org = self.sim.images(start=0, num=self.n)

def testPhaseFlip(self):
self.sim.phase_flip()
imgs_pf = self.sim.images(start=0, num=self.n)

# check energy conservation
self.assertTrue(
np.allclose(
anorm(self.imgs_org.asnumpy(), axes=(1, 2)),
anorm(imgs_pf.asnumpy(), axes=(1, 2)),
)
)

def testDownsample(self):
# generate a 3D map with density decays as Gaussian function
g3d = grid_3d(self.L, dtype=self.dtype)
coords = np.array([g3d["x"].flatten(), g3d["y"].flatten(), g3d["z"].flatten()])
sigma = 0.2
vol = np.exp(-0.5 * np.sum(np.abs(coords / sigma) ** 2, axis=0)).astype(
self.dtype
)
vol = np.reshape(vol, g3d["x"].shape)
vols = Volume(vol)

# set noise to zero and CFT filters to unity for simulation object
noise_var = 0
noise_filter = ScalarFilter(dim=2, value=noise_var)
sim = Simulation(
L=self.L,
n=self.n,
vols=vols,
offsets=0.0,
amplitudes=1.0,
unique_filters=[
ScalarFilter(dim=2, value=1) for d in np.linspace(1.5e4, 2.5e4, 7)
],
noise_filter=noise_filter,
dtype=self.dtype,
)
# get images before downsample
imgs_org = sim.images(start=0, num=self.n)
# get images after downsample
max_resolution = 32
sim.downsample(max_resolution)
imgs_ds = sim.images(start=0, num=self.n)

# Check individual grid points
self.assertTrue(
np.allclose(
imgs_org[:, 32, 32],
imgs_ds[:, 16, 16],
atol=utest_tolerance(self.dtype),
)
)
# check resolution
self.assertTrue(np.allclose(max_resolution, imgs_ds.shape[1]))
# check energy conservation after downsample
self.assertTrue(
np.allclose(
anorm(imgs_org.asnumpy(), axes=(1, 2)) / self.L,
anorm(imgs_ds.asnumpy(), axes=(1, 2)) / max_resolution,
atol=utest_tolerance(self.dtype),
)
)

def testNormBackground(self):
bg_radius = 1.0
grid = grid_2d(self.L)
mask = grid["r"] > bg_radius
self.sim.normalize_background()
imgs_nb = self.sim.images(start=0, num=self.n).asnumpy()
new_mean = np.mean(imgs_nb[:, mask])
new_variance = np.var(imgs_nb[:, mask])

# new mean of noise should be close to zero and variance should be close to 1
self.assertTrue(new_mean < 1e-7 and abs(new_variance - 1) < 1e-7)

def testWhiten(self):
noise_estimator = AnisotropicNoiseEstimator(self.sim)
self.sim.whiten(noise_estimator.filter)
imgs_wt = self.sim.images(start=0, num=self.n).asnumpy()

# calculate correlation between two neighboring pixels from background
corr_coef = np.corrcoef(
imgs_wt[:, self.L - 1, self.L - 1], imgs_wt[:, self.L - 2, self.L - 1]
)

# correlation matrix should be close to identity
self.assertTrue(np.allclose(np.eye(2), corr_coef, atol=1e-1))

def testInvertContrast(self):
sim1 = self.sim
imgs1 = sim1.images(start=0, num=128)
sim1.invert_contrast()
imgs1_rc = sim1.images(start=0, num=128)
# need to set the negative images to the second simulation object
sim2 = ArrayImageSource(-imgs1)
sim2.invert_contrast()
imgs2_rc = sim2.images(start=0, num=128)

# all images should be the same after inverting contrast
self.assertTrue(np.allclose(imgs1_rc.asnumpy(), imgs2_rc.asnumpy()))