Ejemplo n.º 1
0
 def testScaledFilter(self):
     filt1 = CTFFilter(defocus_u=1.5e4, defocus_v=1.5e4)
     scale_value = 2.5
     result1 = filt1.evaluate(self.omega)
     # ScaledFilter scales the pixel size which cancels out
     # a corresponding scaling in omega
     filt2 = ScaledFilter(filt1, scale_value)
     result2 = filt2.evaluate(self.omega * scale_value)
     self.assertTrue(np.allclose(result1, result2, atol=utest_tolerance(self.dtype)))
Ejemplo n.º 2
0
 def testCTFScale(self):
     filt = CTFFilter(defocus_u=1.5e4, defocus_v=1.5e4)
     result1 = filt.evaluate(self.omega)
     scale_value = 2.5
     filt = filt.scale(scale_value)
     # scaling a CTFFilter scales the pixel size which cancels out
     # a corresponding scaling in omega
     result2 = filt.evaluate(self.omega * scale_value)
     self.assertTrue(np.allclose(result1, result2, atol=utest_tolerance(self.dtype)))
Ejemplo n.º 3
0
 def testCTFFilter(self):
     filter = CTFFilter(defocus_u=1.5e4, defocus_v=1.5e4)
     result = filter.evaluate(self.omega)
     self.assertEqual(result.shape, (256,))
Ejemplo n.º 4
0
 def testDualFilter(self):
     ctf_filter = CTFFilter(defocus_u=1.5e4, defocus_v=1.5e4)
     result = ctf_filter.evaluate(-self.omega)
     dual_filter = ctf_filter.dual()
     dual_result = dual_filter.evaluate(self.omega)
     self.assertTrue(np.allclose(result, dual_result))
Ejemplo n.º 5
0
    def __init__(
        self,
        filepath,
        data_folder=None,
        pixel_size=1,
        B=0,
        n_workers=-1,
        max_rows=None,
        memory=None,
    ):
        """
        Load STAR file at given filepath
        :param filepath: Absolute or relative path to STAR file
        :param data_folder: Path to folder w.r.t which all relative paths to .mrcs files are resolved.
            If None, the folder corresponding to filepath is used.
        :param pixel_size: the pixel size of the images in angstroms (Default 1)
        :param B: the envelope decay of the CTF in inverse square angstrom (Default 0)
        :param n_workers: Number of threads to spawn to read referenced .mrcs files (Default -1 to auto detect)
        :param max_rows: Maximum number of rows in STAR file to read. If None, all rows are read.
            Note that this refers to the max number of images to load, not the max. number of .mrcs files (which may be
            equal to or less than the number of images).
        :param memory: str or None
            The path of the base directory to use as a data store or None. If None is given, no caching is performed.
        """
        logger.debug(f"Creating ImageSource from STAR file at path {filepath}")

        self.pixel_size = pixel_size
        self.B = B
        self.n_workers = n_workers

        metadata = self.__class__.starfile2df(filepath, data_folder, max_rows)

        n = len(metadata)
        if n == 0:
            raise RuntimeError("No mrcs files found for starfile!")

        # Peek into the first image and populate some attributes
        first_mrc_filepath = metadata.loc[0]["__mrc_filepath"]
        mrc = mrcfile.open(first_mrc_filepath)

        # Get the 'mode' (data type) - TODO: There's probably a more direct way to do this.
        mode = int(mrc.header.mode)
        dtypes = {0: "int8", 1: "int16", 2: "float32", 6: "uint16"}
        ensure(
            mode in dtypes,
            f"Only modes={list(dtypes.keys())} in MRC files are supported for now.",
        )
        dtype = dtypes[mode]

        shape = mrc.data.shape
        # the code below  accounts for the case where the first MRCS image in the STAR file has one image
        # in that case, the shape will be (resolution, resolution), whereas this code expects
        # (1, resolution, resolution). below, the shape is expanded to accomodate this expectation
        if len(shape) == 2:
            shape = (1,) + shape

        ensure(shape[1] == shape[2], "Only square images are supported")
        L = shape[1]
        logger.debug(f"Image size = {L}x{L}")

        # Save original image resolution that we expect to use when we start reading actual data
        self._original_resolution = L

        filter_params, filter_indices = np.unique(
            metadata[
                [
                    "_rlnVoltage",
                    "_rlnDefocusU",
                    "_rlnDefocusV",
                    "_rlnDefocusAngle",
                    "_rlnSphericalAberration",
                    "_rlnAmplitudeContrast",
                ]
            ].values,
            return_inverse=True,
            axis=0,
        )

        filters = []
        for row in filter_params:
            filters.append(
                CTFFilter(
                    pixel_size=self.pixel_size,
                    voltage=row[0],
                    defocus_u=row[1],
                    defocus_v=row[2],
                    defocus_ang=row[3] * np.pi / 180,  # degrees to radians
                    Cs=row[4],
                    alpha=row[5],
                    B=B,
                )
            )

        ImageSource.__init__(
            self, L=L, n=n, dtype=dtype, metadata=metadata, memory=memory
        )
        self.unique_filters = filters
        self.filter_indices = filter_indices
Ejemplo n.º 6
0
# %%
# Apply a Uniform Shift
# ---------------------

# Apply a single shift to each image.
shifts = np.array([100, 30])
im.shift(shifts).show()

# %%
# Apply Image-wise Shifts
# -----------------------

# Or apply shifts corresponding to to each image.
shifts = np.array([[300 * i, 100 * i] for i in range(1, im.n_images + 1)])
im.shift(shifts).show()

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

im.downsample(80).show()

# %%
# CTF Filter
# ----------

# pixel_size/defous_u/defocus_v in Angstrom, voltage in kV
filter = CTFFilter(pixel_size=1, voltage=100, defocus_u=1500, defocus_v=2000)
im.filter(filter).show()