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)
Ejemplo n.º 2
0
    def setUp(self):
        L = 32
        n = 64
        pixel_size = 5
        voltage = 200
        defocus_min = 1.5e4
        defocus_max = 2.5e4
        defocus_ct = 7
        Cs = 2.0
        alpha = 0.1
        self.dtype = np.float32

        filters = [
            RadialCTFFilter(pixel_size, voltage, defocus=d, Cs=Cs, alpha=alpha)
            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))
        vols = vols.downsample((L * np.ones(3, dtype=int)))

        sim = Simulation(L=L,
                         n=n,
                         vols=vols,
                         unique_filters=filters,
                         dtype=self.dtype)

        self.orient_est = CLSyncVoting(sim, L // 2, 36)
Ejemplo n.º 3
0
    def setUpClass(cls):
        cls.dtype = np.float32
        cls.sim = Simulation(
            n=1024,
            unique_filters=[
                RadialCTFFilter(defocus=d)
                for d in np.linspace(1.5e4, 2.5e4, 7)
            ],
            dtype=cls.dtype,
        )
        basis = FBBasis3D((8, 8, 8), dtype=cls.dtype)
        cls.noise_variance = 0.0030762743633643615

        cls.mean_estimator = MeanEstimator(cls.sim, basis)
        cls.mean_est = Volume(
            np.load(os.path.join(DATA_DIR,
                                 "mean_8_8_8.npy")).astype(cls.dtype))

        # Passing in a mean_kernel argument to the following constructor speeds up some calculations
        cls.covar_estimator = CovarianceEstimator(
            cls.sim,
            basis,
            mean_kernel=cls.mean_estimator.kernel,
            preconditioner="none")
        cls.covar_estimator_with_preconditioner = CovarianceEstimator(
            cls.sim,
            basis,
            mean_kernel=cls.mean_estimator.kernel,
            preconditioner="circulant",
        )
Ejemplo n.º 4
0
 def setUp(self):
     self.sim = Simulation(
         n=1024,
         unique_filters=[
             RadialCTFFilter(defocus=d)
             for d in np.linspace(1.5e4, 2.5e4, 7)
         ],
     )
Ejemplo n.º 5
0
 def setUp(self):
     self.sim = Simulation(
         n=1024,
         L=8,
         unique_filters=[
             RadialCTFFilter(defocus=d)
             for d in np.linspace(1.5e4, 2.5e4, 7)
         ],
         seed=0,
         noise_filter=IdentityFilter(),
         dtype="single",
     )
Ejemplo n.º 6
0
 def setUp(self):
     self.dtype = np.float32
     sim = Simulation(
         n=1024,
         unique_filters=[
             RadialCTFFilter(defocus=d) for d in np.linspace(1.5e4, 2.5e4, 7)
         ],
         dtype=self.dtype,
     )
     basis = FBBasis3D((8, 8, 8), dtype=self.dtype)
     self.estimator = MeanEstimator(sim, basis, preconditioner="none")
     self.estimator_with_preconditioner = MeanEstimator(
         sim, basis, preconditioner="circulant"
     )
Ejemplo n.º 7
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)
Ejemplo n.º 8
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]
Ejemplo n.º 9
0
    def get_mean(self, coeffs, ctf_fb=None, ctf_idx=None):
        """
        Calculate the mean vector from the expansion coefficients with CTF information.

        :param coeffs: A coefficient vector (or an array of coefficient vectors) to be averaged.
        :param ctf_fb: The CFT functions in the FB expansion.
        :param ctf_idx: An array of the CFT function indices for all 2D images.
            If ctf_fb or ctf_idx is None, the identity filter will be applied.
        :return: The mean value vector for all images.
        """

        if coeffs.size == 0:
            raise RuntimeError("The coefficients need to be calculated!")

        # should assert we require none or both...
        if (ctf_fb is None) or (ctf_idx is None):
            ctf_idx = np.zeros(coeffs.shape[0], dtype=int)
            ctf_fb = [
                BlkDiagMatrix.eye_like(RadialCTFFilter().fb_mat(self.basis),
                                       dtype=self.dtype)
            ]

        b = np.zeros(self.basis.count, dtype=coeffs.dtype)

        A = BlkDiagMatrix.zeros_like(ctf_fb[0])
        for k in np.unique(ctf_idx[:]).T:
            coeff_k = coeffs[ctf_idx == k]
            weight = coeff_k.shape[0] / coeffs.shape[0]
            mean_coeff_k = self._get_mean(coeff_k)

            ctf_fb_k = ctf_fb[k]
            ctf_fb_k_t = ctf_fb_k.T
            b += weight * ctf_fb_k_t.apply(mean_coeff_k)
            A += weight * (ctf_fb_k_t @ ctf_fb_k)

        mean_coeff = A.solve(b)
        return mean_coeff
Ejemplo n.º 10
0
    def get_covar(
        self,
        coeffs,
        ctf_fb=None,
        ctf_idx=None,
        mean_coeff=None,
        do_refl=True,
        noise_var=1,
        covar_est_opt=None,
        make_psd=True,
    ):
        """
        Calculate the covariance matrix from the expansion coefficients and CTF information.

        :param coeffs: A coefficient vector (or an array of coefficient vectors) to be calculated.
        :param ctf_fb: The CFT functions in the FB expansion.
        :param ctf_idx: An array of the CFT function indices for all 2D images.
            If ctf_fb or ctf_idx is None, the identity filter will be applied.
        :param mean_coeff: The mean value vector from all images.
        :param noise_var: The estimated variance of noise. The value should be zero for `coeffs`
            from clean images of simulation data.
        :param covar_est_opt: The optimization parameter list for obtaining the Cov2D matrix.
        :param make_psd: If True, make the covariance matrix positive semidefinite
        :return: The basis coefficients of the covariance matrix in
            the form of cell array representing a block diagonal matrix. These
            block diagonal matrices are implemented as BlkDiagMatrix instances.
            The covariance is calculated from the images represented by the coeffs array,
            along with all possible rotations and reflections. As a result, the computed covariance
            matrix is invariant to both reflection and rotation. The effect of the filters in ctf_fb
            are accounted for and inverted to yield a covariance estimate of the unfiltered images.
        """

        if coeffs.size == 0:
            raise RuntimeError("The coefficients need to be calculated!")

        if (ctf_fb is None) or (ctf_idx is None):
            ctf_idx = np.zeros(coeffs.shape[0], dtype=int)
            ctf_fb = [
                BlkDiagMatrix.eye_like(RadialCTFFilter().fb_mat(self.basis))
            ]

        def identity(x):
            return x

        default_est_opt = {
            "shrinker": "None",
            "verbose": 0,
            "max_iter": 250,
            "iter_callback": [],
            "store_iterates": False,
            "rel_tolerance": 1e-12,
            "precision": self.dtype,
            "preconditioner": identity,
        }

        covar_est_opt = fill_struct(covar_est_opt, default_est_opt)

        if mean_coeff is None:
            mean_coeff = self.get_mean(coeffs, ctf_fb, ctf_idx)

        b_coeff = BlkDiagMatrix.zeros_like(ctf_fb[0])
        b_noise = BlkDiagMatrix.zeros_like(ctf_fb[0])
        A = []
        for _ in range(len(ctf_fb)):
            A.append(BlkDiagMatrix.zeros_like(ctf_fb[0]))

        M = BlkDiagMatrix.zeros_like(ctf_fb[0])

        for k in np.unique(ctf_idx[:]):

            coeff_k = coeffs[ctf_idx == k]
            weight = coeff_k.shape[0] / coeffs.shape[0]

            ctf_fb_k = ctf_fb[k]
            ctf_fb_k_t = ctf_fb_k.T
            mean_coeff_k = ctf_fb_k.apply(mean_coeff)
            covar_coeff_k = self._get_covar(coeff_k, mean_coeff_k)

            b_coeff += weight * (ctf_fb_k_t @ covar_coeff_k @ ctf_fb_k)

            ctf_fb_k_sq = ctf_fb_k_t @ ctf_fb_k
            b_noise += weight * ctf_fb_k_sq

            A[k] = np.sqrt(weight) * ctf_fb_k_sq
            M += A[k]

        if not b_coeff.check_psd():
            logger.warning(
                "Left side b in Cov2D is not positive semidefinite.")

        if covar_est_opt["shrinker"] == "None":
            b = b_coeff - noise_var * b_noise
        else:
            b = self.shrink_covar_backward(
                b_coeff,
                b_noise,
                np.size(coeffs, 1),
                noise_var,
                covar_est_opt["shrinker"],
            )
        if not b.check_psd():
            logger.warning("Left side b after removing noise in Cov2D"
                           " is not positive semidefinite.")

        # RCOPT okay, this looks like a big batch, come back later

        cg_opt = covar_est_opt

        covar_coeff = BlkDiagMatrix.zeros_like(ctf_fb[0])

        def precond_fun(S, x):
            p = np.size(S, 0)
            ensure(
                np.size(x) == p * p,
                "The sizes of S and x are not consistent.")
            x = m_reshape(x, (p, p))
            y = S @ x @ S
            y = m_reshape(y, (p**2, ))
            return y

        def apply(A, x):
            p = np.size(A[0], 0)
            x = m_reshape(x, (p, p))
            y = np.zeros_like(x)
            for k in range(0, len(A)):
                y = y + A[k] @ x @ A[k].T
            y = m_reshape(y, (p**2, ))
            return y

        for ell in range(0, len(b)):
            A_ell = []
            for k in range(0, len(A)):
                A_ell.append(A[k][ell])
            p = np.size(A_ell[0], 0)
            b_ell = m_reshape(b[ell], (p**2, ))
            S = inv(M[ell])
            cg_opt["preconditioner"] = lambda x: precond_fun(S, x)
            covar_coeff_ell, _, _ = conj_grad(lambda x: apply(A_ell, x), b_ell,
                                              cg_opt)
            covar_coeff[ell] = m_reshape(covar_coeff_ell, (p, p))

        if not covar_coeff.check_psd():
            logger.warning(
                "Covariance matrix in Cov2D is not positive semidefinite.")
            if make_psd:
                logger.info("Convert matrices to positive semidefinite.")
                covar_coeff = covar_coeff.make_psd()

        return covar_coeff
num_imgs = 128

# Specify the CTF parameters not used for this example
# but necessary for initializing the simulation object
pixel_size = 5  # Pixel size of the images (in angstroms)
voltage = 200  # Voltage (in KV)
defocus_min = 1.5e4  # Minimum defocus value (in angstroms)
defocus_max = 2.5e4  # Maximum defocus value (in angstroms)
defocus_ct = 7  # Number of defocus groups.
Cs = 2.0  # Spherical aberration
alpha = 0.1  # Amplitude contrast

logger.info("Initialize simulation object and CTF filters.")
# Create CTF filters
filters = [
    RadialCTFFilter(pixel_size, voltage, defocus=d, Cs=2.0, alpha=0.1)
    for d in np.linspace(defocus_min, defocus_max, defocus_ct)
]

# %%
# Downsampling
# ------------

# Load the map file of a 70S Ribosome and downsample the 3D map to desired resolution.
# The downsampling should be done by the internal function of Volume object in future.
logger.info(f"Load 3D map and downsample 3D map to desired grids "
            f"of {img_size} x {img_size} x {img_size}.")
infile = mrcfile.open(os.path.join(DATA_DIR, "clean70SRibosome_vol_65p.mrc"))
vols = Volume(infile.data.astype(dtype))
vols = vols.downsample((img_size, ) * 3)
Ejemplo n.º 12
0
    def testRadialCTFFilterMultiplierGrid(self):
        filter = RadialCTFFilter(defocus=2.5e4) * RadialCTFFilter(defocus=2.5e4)
        result = filter.evaluate_grid(8, dtype=self.dtype)

        self.assertEqual(result.shape, (8, 8))
        self.assertTrue(
            np.allclose(
                result,
                np.array(
                    [
                        [
                            0.461755701877834,
                            -0.995184514498978,
                            0.063120922443392,
                            0.833250206225063,
                            0.961464660252150,
                            0.833250206225063,
                            0.063120922443392,
                            -0.995184514498978,
                        ],
                        [
                            -0.995184514498978,
                            0.626977423649552,
                            0.799934516166400,
                            0.004814348317439,
                            -0.298096205735759,
                            0.004814348317439,
                            0.799934516166400,
                            0.626977423649552,
                        ],
                        [
                            0.063120922443392,
                            0.799934516166400,
                            -0.573061561512667,
                            -0.999286510416273,
                            -0.963805291282899,
                            -0.999286510416273,
                            -0.573061561512667,
                            0.799934516166400,
                        ],
                        [
                            0.833250206225063,
                            0.004814348317439,
                            -0.999286510416273,
                            -0.633095739808868,
                            -0.368890743119366,
                            -0.633095739808868,
                            -0.999286510416273,
                            0.004814348317439,
                        ],
                        [
                            0.961464660252150,
                            -0.298096205735759,
                            -0.963805291282899,
                            -0.368890743119366,
                            -0.070000000000000,
                            -0.368890743119366,
                            -0.963805291282899,
                            -0.298096205735759,
                        ],
                        [
                            0.833250206225063,
                            0.004814348317439,
                            -0.999286510416273,
                            -0.633095739808868,
                            -0.368890743119366,
                            -0.633095739808868,
                            -0.999286510416273,
                            0.004814348317439,
                        ],
                        [
                            0.063120922443392,
                            0.799934516166400,
                            -0.573061561512667,
                            -0.999286510416273,
                            -0.963805291282899,
                            -0.999286510416273,
                            -0.573061561512667,
                            0.799934516166400,
                        ],
                        [
                            -0.995184514498978,
                            0.626977423649552,
                            0.799934516166400,
                            0.004814348317439,
                            -0.298096205735759,
                            0.004814348317439,
                            0.799934516166400,
                            0.626977423649552,
                        ],
                    ]
                )
                ** 2,
                atol=utest_tolerance(self.dtype),
            )
        )
Ejemplo n.º 13
0
 def testRadialCTFFilter(self):
     filter = RadialCTFFilter(defocus=2.5e4)
     result = filter.evaluate(self.omega)
     self.assertEqual(result.shape, (256,))
Ejemplo n.º 14
0
# %%
# Create Simulation Object
# ------------------------

# Specify parameters
num_vols = 2  # number of volumes
img_size = 8  # image size in square
num_imgs = 1024  # number of images
num_eigs = 16  # number of eigen-vectors to keep

# Create a simulation object with specified filters
sim = Simulation(
    L=img_size,
    n=num_imgs,
    C=num_vols,
    unique_filters=[RadialCTFFilter(defocus=d) for d in np.linspace(1.5e4, 2.5e4, 7)],
)

# Specify the normal FB basis method for expending the 2D images
basis = FBBasis3D((img_size, img_size, img_size))

# Estimate the noise variance. This is needed for the covariance estimation step below.
noise_estimator = WhiteNoiseEstimator(sim, batchSize=500)
noise_variance = noise_estimator.estimate()
logger.info(f"Noise Variance = {noise_variance}")

# %%
# Estimate Mean Volume and Covariance
# -----------------------------------
#
# Estimate the mean. This uses conjugate gradient on the normal equations for
Ejemplo n.º 15
0
logger = logging.getLogger(__name__)

# Specify parameters
num_vols = 2  # number of volumes
img_size = 8  # image size in square
num_imgs = 1024  # number of images
num_eigs = 16  # number of eigen-vectors to keep

# Create a simulation object with specified filters
sim = Simulation(
    L=img_size,
    n=num_imgs,
    C=num_vols,
    unique_filters=[
        RadialCTFFilter(defocus=d) for d in np.linspace(1.5e4, 2.5e4, 7)
    ],
)

# Specify the normal FB basis method for expending the 2D images
basis = FBBasis3D((img_size, img_size, img_size))

# Estimate the noise variance. This is needed for the covariance estimation step below.
noise_estimator = WhiteNoiseEstimator(sim, batchSize=500)
noise_variance = noise_estimator.estimate()
logger.info(f"Noise Variance = {noise_variance}")

# Estimate the mean. This uses conjugate gradient on the normal equations for
# the least-squares estimator of the mean volume. The mean volume is represented internally
# using the basis object, but the output is in the form of an
# L-by-L-by-L array.