예제 #1
0
    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 setUp(self):
        n = 32
        L = 8
        filters = [
            RadialCTFFilter(5, 200, defocus=d, Cs=2.0, alpha=0.1)
            for d in np.linspace(1.5e4, 2.5e4, 7)
        ]
        self.dtype = np.float32
        self.noise_var = 0.1848

        # Initial noise filter to generate noise images.
        # Noise variance is set to a value far away that is used to calculate
        # covariance matrix and CWF coefficients in order to check the function
        # for rebuilding positive definite covariance matrix.
        noise_filter = ScalarFilter(dim=2, value=self.noise_var * 0.001)

        self.src = Simulation(L,
                              n,
                              unique_filters=filters,
                              dtype=self.dtype,
                              noise_filter=noise_filter)
        self.basis = FFBBasis2D((L, L), dtype=self.dtype)
        self.coeff = self.basis.evaluate_t(self.src.images(0, self.src.n))

        self.ctf_idx = self.src.filter_indices
        self.ctf_fb = [f.fb_mat(self.basis) for f in self.src.unique_filters]

        self.cov2d = RotCov2D(self.basis)
        self.bcov2d = BatchedRotCov2D(self.src, self.basis, batch_size=7)
예제 #3
0
def denoise(
    data_folder,
    starfile_in,
    starfile_out,
    pixel_size,
    max_rows,
    max_resolution,
    noise_type,
    denoise_method,
):
    """
    Denoise the images and output the clean images using the default CWF method.
    """
    # Create a source object for 2D images
    logger.info(
        f"Read in images from {starfile_in} and preprocess the images.")
    source = RelionSource(starfile_in,
                          data_folder,
                          pixel_size=pixel_size,
                          max_rows=max_rows)

    logger.info(f"Set the resolution to {max_resolution} X {max_resolution}")
    if max_resolution < source.L:
        # Downsample the images
        source.downsample(max_resolution)
    else:
        logger.warn(
            f"Unable to downsample to {max_resolution}, using {source.L}")
    source.cache()

    # Specify the fast FB basis method for expending the 2D images
    basis = FFBBasis2D((source.L, source.L))

    # Estimate the noise of images
    noise_estimator = None
    if noise_type == "White":
        logger.info("Estimate the noise of images using white noise method")
        noise_estimator = WhiteNoiseEstimator(source)
    elif noise_type == "Anisotropic":
        logger.info("Estimate the noise of images using anisotropic method")
        noise_estimator = AnisotropicNoiseEstimator(source)
    else:
        raise RuntimeError(f"Unsupported noise_type={noise_type}")

    # Whiten the noise of images
    logger.info("Whiten the noise of images from the noise estimator")
    source.whiten(noise_estimator.filter)

    if denoise_method == "CWF":
        logger.info("Denoise the images using CWF cov2D method.")
        denoiser = DenoiserCov2D(source, basis)
        denoised_src = denoiser.denoise(batch_size=512)
        denoised_src.save(starfile_out,
                          batch_size=512,
                          save_mode="single",
                          overwrite=False)
    else:
        raise NotImplementedError(
            "Currently only covariance Wiener filtering method is supported")
예제 #4
0
    def setUp(self):
        self.dtype = np.float32

        L = 8
        n = 32
        pixel_size = 5.0 * 65 / L
        voltage = 200
        defocus_min = 1.5e4
        defocus_max = 2.5e4
        defocus_ct = 7

        self.noise_var = 1.3957e-4
        noise_filter = ScalarFilter(dim=2, value=self.noise_var)

        unique_filters = [
            RadialCTFFilter(pixel_size, voltage, defocus=d, Cs=2.0, alpha=0.1)
            for d in np.linspace(defocus_min, defocus_max, defocus_ct)
        ]

        vols = Volume(
            np.load(os.path.join(DATA_DIR, "clean70SRibosome_vol.npy")).astype(
                self.dtype
            )
        )  # RCOPT
        vols = vols.downsample((L * np.ones(3, dtype=int))) * 1.0e3
        # Since FFBBasis2D doesn't yet implement dtype, we'll set this to double to match its built in types.
        sim = Simulation(
            n=n,
            L=L,
            vols=vols,
            unique_filters=unique_filters,
            offsets=0.0,
            amplitudes=1.0,
            dtype=self.dtype,
            noise_filter=noise_filter,
        )

        self.basis = FFBBasis2D((L, L), dtype=self.dtype)

        self.h_idx = sim.filter_indices
        self.h_ctf_fb = [filt.fb_mat(self.basis) for filt in unique_filters]

        self.imgs_clean = sim.projections()
        self.imgs_ctf_clean = sim.clean_images()
        self.imgs_ctf_noise = sim.images(start=0, num=n)

        self.cov2d = RotCov2D(self.basis)
        self.coeff_clean = self.basis.evaluate_t(self.imgs_clean)
        self.coeff = self.basis.evaluate_t(self.imgs_ctf_noise)
예제 #5
0
    def setUp(self):

        self.vols = Volume(
            np.load(os.path.join(DATA_DIR,
                                 "clean70SRibosome_vol.npy"))).downsample(17)

        self.resolution = self.vols.resolution
        self.n_img = 3
        self.dtype = np.float64

        # Create a Basis to use in alignment.
        self.basis = FFBBasis2D((self.resolution, self.resolution),
                                dtype=self.dtype)

        # This sets up a trivial class, where there is one group having all images.
        self.classes = np.arange(self.n_img, dtype=int).reshape(1, self.n_img)
        self.reflections = np.zeros(self.classes.shape, dtype=bool)
예제 #6
0
    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))
예제 #7
0
    def _build(self):
        src = self.src

        if self.basis is None:
            from aspire.basis import FFBBasis2D

            self.basis = FFBBasis2D((src.L, src.L), dtype=self.dtype)

        if src.unique_filters is None:
            logger.info("CTF filters are not included in Cov2D denoising")
            # set all CTF filters to an identity filter
            self.ctf_idx = np.zeros(src.n, dtype=int)
            self.ctf_fb = [
                BlkDiagMatrix.eye_like(RadialCTFFilter().fb_mat(self.basis))
            ]
        else:
            logger.info("Represent CTF filters in FB basis")
            unique_filters = src.unique_filters
            self.ctf_idx = src.filter_indices
            self.ctf_fb = [f.fb_mat(self.basis) for f in unique_filters]
예제 #8
0
    def __init__(self, src, basis=None, noise_var=None, components=400):
        """

        :param src: Source instance
        :param basis: Optional Fourier Bessel Basis (usually FFBBasis2D)
        :param noise_var: None estimates noise (default).
        0 forces "clean" treatment (no weighting).
        Other values assigned to noise_var.
        """

        self.src = src

        # Automatically generate basis if needed.
        if basis is None:
            basis = FFBBasis2D((self.src.L, ) * 2, dtype=self.src.dtype)
        self.basis = basis

        # Components are used for `compress` during `build`.
        self.components = components

        # check/warn dtypes
        self.dtype = self.src.dtype
        if self.basis.dtype != self.dtype:
            logger.warning(f"basis.dtype {self.basis.dtype} does not match"
                           f" source {self.src.dtype}, using {self.dtype}.")

        self.count = self.basis.count
        self.complex_count = self.basis.complex_count
        self.angular_indices = self.basis.angular_indices
        self.radial_indices = self.basis.radial_indices
        self.signs_indices = self.basis._indices["sgns"]
        self.complex_angular_indices = self.basis.complex_angular_indices
        self.complex_radial_indices = self.basis.complex_radial_indices

        self.complex_indices_map = self._get_complex_indices_map()
        assert (len(self.complex_indices_map) == self.complex_count
                ), f"{len(self.complex_indices_map)} != {self.complex_count}"

        self.noise_var = noise_var  # noise_var is handled during `build` call.

        self.build()
예제 #9
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)
예제 #10
0
# Create a simulation object with specified filters and the downsampled 3D map
logger.info("Use downsampled map to creat simulation object.")
sim = Simulation(
    L=img_size,
    n=num_imgs,
    vols=vols,
    unique_filters=ctf_filters,
    offsets=0.0,
    amplitudes=1.0,
    dtype=dtype,
    noise_filter=noise_filter,
)

# Specify the fast FB basis method for expending the 2D images
ffbbasis = FFBBasis2D((img_size, img_size), dtype=dtype)

# Assign the CTF information and index for each image
h_idx = sim.filter_indices

# Evaluate CTF in the 8X8 FB basis
h_ctf_fb = [filt.fb_mat(ffbbasis) for filt in ctf_filters]

# Get clean images from projections of 3D map.
logger.info("Apply CTF filters to clean images.")
imgs_clean = sim.projections()
imgs_ctf_clean = sim.clean_images()
power_clean = imgs_ctf_clean.norm() ** 2 / imgs_ctf_clean.size
sn_ratio = power_clean / noise_var
logger.info(f"Signal to noise ratio is {sn_ratio}.")
예제 #11
0
 def setUp(self):
     self.dtype = np.float32  # Required for convergence of this test
     self.L = 8
     self.basis = FFBBasis2D((self.L, self.L), dtype=self.dtype)
예제 #12
0
plt.subplot(1, 3, 2)
plt.imshow(np.real(fb_images[0]), cmap="gray")
plt.title("FB Image")
plt.subplot(1, 3, 3)
plt.imshow(np.real(org_images[0] - fb_images[0]), cmap="gray")
plt.title("Differences")
plt.tight_layout()

# %%
# Expand Images with Fast FB Basis Method
# ---------------------------------------

# Specify the fast FB basis method for expanding the 2D images
# Note, we'll set the Basis dtype to be the same as the `org_image` data,
#  as good practice.
ffb_basis = FFBBasis2D((img_size, img_size), dtype=org_images.dtype)

# Get the expansion coefficients based on fast FB basis
logger.info("start fast FB expansion of original images.")
tstart = timeit.default_timer()
ffb_coeffs = ffb_basis.evaluate_t(org_images)
tstop = timeit.default_timer()
dtime = tstop - tstart
logger.info(
    f"Finish fast FB expansion of original images in {dtime:.4f} seconds.")

# Reconstruct images from the expansion coefficients based on fast FB basis
ffb_images = ffb_basis.evaluate(ffb_coeffs)
logger.info(
    "Finish reconstruction of images from fast FB expansion coefficients.")