def setUp(self):
        self.dtype = np.float32

        # Test Volume
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype)).downsample(32)

        # Create Sim object.
        # Creates 10 projects so there is something to feed FSPCABasis.
        self.src = Simulation(L=v.resolution, n=10, vols=v, dtype=v.dtype)

        # Original projection image to transform.
        self.orig_img = self.src.images(0, 1)

        # Rotate 90 degrees in cartesian coordinates using third party tool.
        self.rt90_img = Image(np.rot90(self.orig_img.asnumpy(), axes=(1, 2)))

        # Prepare a Fourier Bessel Basis
        self.basis = FFBBasis2D((self.orig_img.res, ) * 2, dtype=self.dtype)
        self.v1 = self.basis.evaluate_t(self.orig_img)
        self.v2 = self.basis.evaluate_t(self.rt90_img)
        # These should _not_ be equal or the test is pointless.
        self.assertFalse(np.allclose(self.v1, self.v2))

        # Prepare a FSPCA Basis too.
        self.fspca_basis = FSPCABasis(self.src, self.basis)
    def testRotate(self):
        # Now low res (8x8) had problems;
        #  better with odd (7x7), but still not good.
        # We'll use a higher res test image.
        # fh = np.load(os.path.join(DATA_DIR, 'ffbbasis2d_xcoeff_in_8_8.npy'))[:7,:7]
        # Use a real data volume to generate a clean test image.
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                np.float64))
        src = Simulation(L=v.resolution, n=1, vols=v, dtype=v.dtype)
        # Extract, this is the original image to transform.
        x1 = src.images(0, 1)

        # Rotate 90 degrees in cartesian coordinates.
        x2 = Image(np.rot90(x1.asnumpy(), axes=(1, 2)))

        # Express in an FB basis
        basis = FFBBasis2D((x1.res, ) * 2, dtype=x1.dtype)
        v1 = basis.evaluate_t(x1)
        v2 = basis.evaluate_t(x2)
        v3 = basis.evaluate_t(x1)
        v4 = basis.evaluate_t(x1)

        # Reflect in the FB basis space
        v4 = basis.rotate(v1, 0, refl=[True])

        # Rotate in the FB basis space
        v3 = basis.rotate(v1, 2 * np.pi)
        v1 = basis.rotate(v1, -np.pi / 2)

        # Evaluate back into cartesian
        y1 = basis.evaluate(v1)
        y2 = basis.evaluate(v2)
        y3 = basis.evaluate(v3)
        y4 = basis.evaluate(v4)

        # Rotate 90
        self.assertTrue(np.allclose(y1[0], y2[0], atol=1e-4))

        # 2*pi Identity
        self.assertTrue(
            np.allclose(x1[0], y3[0], atol=utest_tolerance(self.dtype)))

        # Refl (flipped using flipud)
        self.assertTrue(np.allclose(np.flipud(x1[0]), y4[0], atol=1e-4))
 def setUp(self):
     self.dtype = np.float32
     self.sim = Simulation(
         n=1024,
         unique_filters=[
             RadialCTFFilter(defocus=d)
             for d in np.linspace(1.5e4, 2.5e4, 7)
         ],
         dtype=self.dtype,
     )
Esempio n. 4
0
    def setUp(self):
        self.resolution = 16
        self.dtype = np.float64

        # Create some projections
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype))
        v = v.downsample(self.resolution)

        # Clean
        self.clean_src = Simulation(
            L=self.resolution,
            n=321,
            vols=v,
            dtype=self.dtype,
        )

        # With Noise
        noise_var = 0.01 * np.var(np.sum(v[0], axis=0))
        noise_filter = ScalarFilter(dim=2, value=noise_var)
        self.noisy_src = Simulation(
            L=self.resolution,
            n=123,
            vols=v,
            dtype=self.dtype,
            noise_filter=noise_filter,
        )

        # Set up FFB
        # Setup a Basis
        self.basis = FFBBasis2D((self.resolution, self.resolution),
                                dtype=self.dtype)

        # Create Basis, use precomputed Basis
        self.clean_fspca_basis = FSPCABasis(
            self.clean_src, self.basis, noise_var=0
        )  # Note noise_var assigned zero, skips eigval filtering.

        # Ceate another fspca_basis, use autogeneration FFB2D Basis
        self.noisy_fspca_basis = FSPCABasis(self.noisy_src)
    def testShift(self):
        """
        Compare shifting using Image with shifting provided by the Basis.

        Note the Basis shift method converts from FB to Image space and back.
        """

        n_img = 3
        test_shift = np.array([10, 2])

        # Construct some synthetic data
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                np.float64)).downsample(self.L)

        src = Simulation(L=self.L, n=n_img, vols=v, dtype=np.float64)

        # Shift images using the Image method directly
        shifted_imgs = src.images(0, n_img).shift(test_shift)

        # Convert original images to basis coefficients
        f_imgs = self.basis.evaluate_t(src.images(0, n_img))

        # Use the basis shift method
        f_shifted_imgs = self.basis.shift(f_imgs, test_shift)

        # Compute diff between the shifted image sets
        diff = shifted_imgs.asnumpy() - self.basis.evaluate(
            f_shifted_imgs).asnumpy()

        # Compute mask to compare only the core of the shifted images
        g = grid_2d(self.L, normalized=False)
        mask = g["r"] > self.L / 2
        # Masking values outside radius to 0
        diff = np.where(mask, 0, diff)

        # Compute and check error
        rmse = np.sqrt(np.mean(np.square(diff), axis=(1, 2)))
        logger.info(f"RMSE shifted image diffs {rmse}")
        self.assertTrue(np.allclose(rmse, 0, atol=1e-5))
Esempio n. 6
0
    def setUp(self):
        self.resolution = 16
        self.dtype = np.float32

        # Get a volume
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype))
        v = v.downsample(self.resolution)

        # Create a src from the volume
        self.src = Simulation(
            L=self.resolution,
            n=321,
            vols=v,
            dtype=self.dtype,
        )

        # Calculate some projection images
        self.imgs = self.src.images(0, self.src.n)

        # Configure an FSPCA basis
        self.fspca_basis = FSPCABasis(self.src, noise_var=0)
Esempio n. 7
0
    def _getSrc(self):
        if not hasattr(self, "shifts"):
            self.shifts = np.zeros((self.n_img, 2))

        return Simulation(
            vols=self.vols,
            L=self.resolution,
            n=self.n_img,
            C=1,
            angles=self.rots.angles,
            offsets=self.shifts,
            amplitudes=np.ones(self.n_img),
            seed=12345,
            dtype=self.dtype,
        )
    def setUp(self):
        self.dtype = np.float32
        self.resolution = 8

        self.n = 1024

        # Generate a stack of images
        self.sim = sim = Simulation(
            n=self.n,
            L=self.resolution,
            unique_filters=[IdentityFilter()],
            seed=0,
            dtype=self.dtype,
            # We'll use random angles
            offsets=np.zeros((self.n, 2)),  # No offsets
            amplitudes=np.ones((self.n)),  # Constant amplitudes
        )

        # Expose images as numpy array.
        self.ims_np = sim.images(0, sim.n).asnumpy()
        self.im = Image(self.ims_np)

        # Vol estimation requires a 3D basis
        self.basis = FBBasis3D((self.resolution,) * 3, dtype=self.dtype)
Esempio n. 9
0
class FSPCATestCase(TestCase):
    def setUp(self):
        self.resolution = 16
        self.dtype = np.float32

        # Get a volume
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype))
        v = v.downsample(self.resolution)

        # Create a src from the volume
        self.src = Simulation(
            L=self.resolution,
            n=321,
            vols=v,
            dtype=self.dtype,
        )

        # Calculate some projection images
        self.imgs = self.src.images(0, self.src.n)

        # Configure an FSPCA basis
        self.fspca_basis = FSPCABasis(self.src, noise_var=0)

    def testExpandEval(self):
        coef = self.fspca_basis.expand_from_image_basis(self.imgs)
        recon = self.fspca_basis.evaluate_to_image_basis(coef)

        # Check recon is close to imgs
        rmse = np.sqrt(
            np.mean(np.square(self.imgs.asnumpy() - recon.asnumpy())))
        logger.info(f"FSPCA Expand Eval Image Round Trupe RMSE: {rmse}")
        self.assertTrue(rmse < utest_tolerance(self.dtype))

    def testComplexConversionErrors(self):
        """
        Test we raise when passed incorrect dtypes.

        Also checks we can handle 0d vector in `to_real`.

        Most other cases covered by classification unit tests.
        """

        with pytest.raises(
                TypeError,
                match="coef provided to to_complex should be real."):
            _ = self.fspca_basis.to_complex(
                np.arange(self.fspca_basis.count, dtype=np.complex64))

        with pytest.raises(
                TypeError,
                match="coef provided to to_real should be complex."):
            _ = self.fspca_basis.to_real(
                np.arange(self.fspca_basis.count, dtype=np.float32).flatten())

    def testRotate(self):
        """
        Trivial test of rotation in FSPCA Basis.

        Also covers to_real and to_complex conversions in FSPCA Basis.
        """
        coef = self.fspca_basis.expand_from_image_basis(self.imgs)
        # rotate by pi
        rot_coef = self.fspca_basis.rotate(coef, radians=np.pi)
        rot_imgs = self.fspca_basis.evaluate_to_image_basis(rot_coef)

        for i, img in enumerate(self.imgs):
            rmse = np.sqrt(np.mean(np.square(np.flip(img) - rot_imgs[i])))
            self.assertTrue(rmse < 10 * utest_tolerance(self.dtype))
#
# For now we will build up to the creation and application of synthetic data set based on the real volume data used previously.

# %%
# ``Simulation`` Class
# --------------------
#
# Generating realistic synthetic data sources is a common task.
# The process of generating then projecting random rotations is integrated into the
# `Simulation <https://computationalcryoem.github.io/ASPIRE-Python/aspire.source.html#module-aspire.source.simulation>`_ class.
# Using ``Simulation``, we can generate arbitrary numbers of projections for use in experiments.
# Later we will demonstrate additional features which allow us to create more realistic data sources.

num_imgs = 100  # How many images in our source.
# Generate a Simulation instance based on the original volume data.
sim = Simulation(L=v.resolution, n=num_imgs, vols=v)
# Display the first 10 images
sim.images(0, 10).show()  # Hi Res

# Repeat for the lower resolution (downsampled) volume v2.
sim2 = Simulation(L=v2.resolution, n=num_imgs, vols=v2)
sim2.images(0, 10).show()  # Lo Res

# Note both of those simulations have the same rotations
#   because they had the same seed by default,
# We can set our own seed to get a different random samples (of rotations).
sim_seed = Simulation(L=v.resolution, n=num_imgs, vols=v, seed=42)
sim_seed.images(0, 10).show()

# We can also view the rotations used to create these projections
# logger.info(sim2.rots)  # Commented due to long output
Esempio n. 11
0
class BispectrumTestCase(TestCase):
    def setUp(self):
        self.dtype = np.float32

        # Test Volume
        v = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype)).downsample(32)

        # Create Sim object.
        # Creates 10 projects so there is something to feed FSPCABasis.
        self.src = Simulation(L=v.resolution, n=10, vols=v, dtype=v.dtype)

        # Original projection image to transform.
        self.orig_img = self.src.images(0, 1)

        # Rotate 90 degrees in cartesian coordinates using third party tool.
        self.rt90_img = Image(np.rot90(self.orig_img.asnumpy(), axes=(1, 2)))

        # Prepare a Fourier Bessel Basis
        self.basis = FFBBasis2D((self.orig_img.res, ) * 2, dtype=self.dtype)
        self.v1 = self.basis.evaluate_t(self.orig_img)
        self.v2 = self.basis.evaluate_t(self.rt90_img)
        # These should _not_ be equal or the test is pointless.
        self.assertFalse(np.allclose(self.v1, self.v2))

        # Prepare a FSPCA Basis too.
        self.fspca_basis = FSPCABasis(self.src, self.basis)

    def testRotationalInvarianceFB(self):
        """
        Compare FB/FFB bispectrums before and after rotation.
        Compares a slab of 3d bispectrum (k1 q1) x (k2 q2) x q3,
        by freq_cutoff of q3 to reduce size.
        """

        # Compute Bispectrum
        q = 3  # slab cutoff
        # We'll also excercise some other options to check they don't crash
        b1 = self.basis.calculate_bispectrum(self.v1,
                                             freq_cutoff=q,
                                             flatten=True,
                                             filter_nonzero_freqs=True)
        b2 = self.basis.calculate_bispectrum(self.v2,
                                             freq_cutoff=q,
                                             flatten=True,
                                             filter_nonzero_freqs=True)

        # Bispectrum should be equivalent
        self.assertTrue(np.allclose(b1, b2))

    def testRotationalInvarianceFSPCA(self):
        """
        Compare FSPCA bispctrum before and after rotation.
        """

        # Compute Bispectrum
        w1 = self.fspca_basis.calculate_bispectrum(self.v1)
        w2 = self.fspca_basis.calculate_bispectrum(self.v2)

        # Bispectrum should be equivalent
        self.assertTrue(np.allclose(w1, w2))

    def testRotationalInvarianceFSPCACompressed(self):
        """
        Compare Compressed FSPCA bispctrum before and after rotation.

        This is most like what is used in practice for RIR.
        """

        # Create a reduced rank (compressed) FSPCABasis, top 100 components.
        components = 100
        compressed_fspca = FSPCABasis(self.src,
                                      self.basis,
                                      components=components)

        # Compress using representation in the compressed FSPCA
        cv1_r = compressed_fspca.expand(self.v1)
        cv2_r = compressed_fspca.expand(self.v2)

        # Check we are really compressed
        self.assertTrue(compressed_fspca.complex_count == components)

        # Compute Bispectrum
        w1 = compressed_fspca.calculate_bispectrum(cv1_r)
        w2 = compressed_fspca.calculate_bispectrum(cv2_r)

        # Bispectrum should be equivalent
        self.assertTrue(np.allclose(w1, w2))