Exemple #1
0
    def apply(self, data, rotation=None):
        """
        @param rotation: apply rotation to the wedge first
        """
        # if no missing wedge
        if self.start_ang == -90 and self.end_ang == 90:
            return data

        if self._volume is not None and np.array_equal(self._volume_shape,
                                                       data.shape):
            pass
        else:
            self._create_wedge_volume(data.shape)

        if rotation is not None:  # rotate the wedge first
            assert len(rotation) == 3
            from pytom.tompy.transform import rotate3d, fourier_reduced2full, fourier_full2reduced, fftshift, ifftshift
            isodd = self._volume_shape[2] % 2
            filter_vol = fftshift(fourier_reduced2full(self._volume, isodd))
            filter_vol = rotate3d(filter_vol,
                                  rotation[0],
                                  rotation[1],
                                  rotation[2],
                                  order=1)  # linear interp!
            filter_vol = fourier_full2reduced(ifftshift(filter_vol))
        else:
            filter_vol = self._volume

        from pytom.tompy.transform import fourier_filter
        res = fourier_filter(data, filter_vol, False)

        return res
Exemple #2
0
    def returnWedgeVolume(self, size, rotation=None):
        """Return the wedge volume in full size and zero in the center
        @param size: size of wedge
        @type size: C{list}
        @param rotation: rotation (3-dim vector if Euler angles)
        @type rotation: C{list}
        @return: wedge volume
        @rtype: Numpy array
        """
        assert len(size) == 3, "returnWedgeVolume: size must be 3-dim list"

        if self._volume is not None and np.array_equal(self._volume_shape,
                                                       size):
            pass
        else:
            self._create_wedge_volume(size)

        from pytom.tompy.transform import rotate3d, fourier_reduced2full, fftshift
        isodd = self._volume_shape[2] % 2
        wedge_vol = fftshift(fourier_reduced2full(self._volume, isodd))
        if rotation is not None:  # rotate the wedge first
            assert len(rotation) == 3
            wedge_vol = rotate3d(wedge_vol,
                                 rotation[0],
                                 rotation[1],
                                 rotation[2],
                                 order=1)

        return wedge_vol
Exemple #3
0
    def toSphericalFunc(self, bw, radius=None, threshold=0.5):
        """Convert the wedge from k-space to a spherical function. \
        currently some hard-coded parameters in - bw <=128, r=45 for max bw, default vol 100
        
        @param bw: bandwidth of the spherical function (must be <=128).
        @param radius: radius in k-space. For general Wedge, not used for SingleTiltWedge.
        @param threshold: threshold, above which the value there would be set to 1.

        @return: a spherical function in numpy.array - default 100x100x100 if no self.vol defined
        """
        assert (bw <= 128), "toSphericalFunc: bw currently limited to <= 128"

        # if no missing wedge
        if self.start_ang == -90 and self.end_ang == 90:
            self._sf = np.ones((4 * bw**2, ))
            return self._sf

        r = 45  # this radius and the volume size should be sufficient for sampling b <= 128
        if self._volume is None or np.min(self._volume.shape) < 100:
            self._create_wedge_volume((100, 100, 100))

        if self._bw == bw and self._sf is not None:
            return self._sf
        else:
            self._bw = bw

        from pytom.tompy.transform import fourier_reduced2full, fftshift
        isodd = self._volume_shape[2] % 2
        filter_vol = fftshift(fourier_reduced2full(self._volume, isodd))

        # start sampling
        from math import pi, sin, cos
        res = []

        for j in range(2 * bw):
            for k in range(2 * bw):
                the = pi * (2 * j + 1) / (4 * bw)  # (0,pi)
                phi = pi * k / bw  # [0,2*pi)

                # this part actually needs interpolation
                x = int(cos(phi) * sin(the) * r + 50)
                y = int(sin(phi) * sin(the) * r + 50)
                z = int(cos(the) * r + 50)

                # if the value is bigger than the threshold, we include it
                if filter_vol[x, y, z] > threshold:
                    res.append(1.0)
                else:
                    res.append(0.0)

        # store it so that we don't have to recompute it next time
        self._sf = np.array(res)

        return self._sf
Exemple #4
0
    def set_wedge_volume(self, wedge_vol, half=True, isodd=False):
        if half:
            self._volume = wedge_vol

            # human understandable version with 0-freq in the center
            from transform import fourier_reduced2full, fftshift
            self._whole_volume = fftshift(
                fourier_reduced2full(self._volume, isodd))
        else:
            self._whole_volume = wedge_vol

            from transform import fourier_full2reduced, ifftshift
            self._volume = fourier_full2reduced(ifftshift(self._whole_volume))
Exemple #5
0
def rotateWeighting(weighting, rotation, mask=None, binarize=False):
    """
    rotateWeighting: Rotates a frequency weighting volume around the center. If the volume provided is reduced complex, it will be rescaled to full size, ftshifted, rotated, iftshifted and scaled back to reduced size.
    @param weighting: A weighting volume in reduced complex convention
    @type weighting: cupy or numpy array
    @param rotation: rotation angles in zxz order
    @type rotation: list
    @param mask:=None is there a rotation mask? A mask with all = 1 will be generated otherwise. Such mask should be \
        provided anyway.
    @type mask: cupy or numpy ndarray
    @return: weight as reduced complex volume
    @rtype: L{pytom_volume.vol_comp}
    """
    from pytom_volume import vol, limit, vol_comp
    from pytom_volume import rotate
    from pytom.voltools import transform
    assert type(weighting) == vol or type(
        weighting
    ) == vol_comp, "rotateWeighting: input neither vol nor vol_comp"
    from pytom.tompy.transform import fourier_reduced2full, fourier_full2reduced

    weighting = fourier_reduced2full(weighting,
                                     isodd=weighting.shape[0] % 2 == 1)
    weighting = xp.fft.fftshift(weighting)

    weightingRotated = xp.zeros_like(weighting)

    transform(weighting,
              output=weightingRotated,
              rotation=rotation,
              rotation_order='rzxz',
              device=device,
              interpolation='filt_bspline')

    if not mask is None:
        weightingRotated *= mask

    weightingRotated = xp.fft.fftshift(weightingRotated)
    returnVolume = fourier_full2reduced(weightingRotated)

    if binarize:
        returnVolume[returnVolume < 0.5] = 0
        returnVolume[returnVolume >= 0.5] = 1

    return returnVolume