Beispiel #1
0
    def average(self, mask=None):
        """
        average Image Stack

        @param mask: mask is multiplied with average if specified
        @type mask: L{pytom_volume.vol}
        @return: average
        @rtype: L{ptom_volume.vol}
        """
        from pytom.basic.transformations import general_transform2d

        if self.averageData == None:
            self.averageData = vol(self.dimX, self.dimY, 1)
        self.averageData.setAll(0.)
        for ii in range(0, len(self.images)):
            self.imageCopies[ii].data = general_transform2d(
                v=self.images[ii].data,
                rot=-self.images[ii].rotation,
                shift=[-self.images[ii].shiftX, -self.images[ii].shiftY],
                scale=1.,
                order=[2, 1, 0],
                crop=True)
            self.averageData = self.averageData + self.imageCopies[ii].data
        if mask:
            self.averageData = self.averageData * mask
        return self.averageData
 def test_Origin(self):
     """
     test that central voxel remains invariant upon magification
     """
     newvol = general_transform2d(self.origin,
                                  rot=0.,
                                  shift=None,
                                  scale=self.m)
     val = newvol.getV(128, 128, 0)
     self.assertTrue(val > 0.01,
                     'origin changes upon magnification change!')
 def test_Transform(self):
     """
     """
     # first magnify by m, then rotate by alpha
     alpha = 25.
     self.r_trans = rotate_vector(self.r, alpha)
     self.r_trans = self.r_trans * self.m
     r_trans_round = array([0., 0.])
     tline = "Approximate position after rotation and magnification: "
     for ii in range(0, 2):
         r_trans_round[ii] = int(round(self.r_trans[ii]) + 128)
         tline = tline + ("%6d " % r_trans_round[ii])
     print(tline)
     newvol = general_transform2d(self.myVol,
                                  rot=alpha,
                                  shift=None,
                                  scale=self.m)
     val = newvol.getV(int(r_trans_round[0]), int(r_trans_round[1]), 0)
     print("value at approximate interpolated position: %5.3f" % val)
     tline = (
         "next neighbors: %5.3f, " %
         newvol.getV(int(r_trans_round[0]) - 1, int(r_trans_round[1]), 0))
     tline = tline + ("%5.3f, " % newvol.getV(
         int(r_trans_round[0]) - 1, int(r_trans_round[1]), 0))
     tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0]),
                                              int(r_trans_round[1]) - 1, 0))
     tline = tline + ("%5.3f, " % newvol.getV(
         int(r_trans_round[0]) + 1, int(r_trans_round[1]), 0))
     tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0]),
                                              int(r_trans_round[1]) + 1, 0))
     tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] + 1),
                                              int(r_trans_round[1]) + 1, 0))
     tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] + 1),
                                              int(r_trans_round[1]) - 1, 0))
     tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] - 1),
                                              int(r_trans_round[1]) + 1, 0))
     tline = tline + ("%5.3f\n" % newvol.getV(int(r_trans_round[0] - 1),
                                              int(r_trans_round[1]) - 1, 0))
     print(tline)
     self.assertTrue(val > 0.01, 'wrong point !=0!')
Beispiel #4
0
def writeAlignedProjections(TiltSeries_,
                            weighting=None,
                            lowpassFilter=None,
                            binning=None,
                            verbose=False,
                            write_images=True):
    """write weighted and aligned projections to disk1

       @param TiltSeries_: Tilt Series
       @type TiltSeries_: reconstruction.TiltSeries
       @param weighting: weighting (<0: analytical weighting, >1 exact weighting (value corresponds to object diameter in pixel AFTER binning)
       @type weighting: float
       @param lowpassFilter: lowpass filter (in Nyquist)
       @type lowpassFilter: float
       @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc.

       @author: FF
    """
    import numpy
    from pytom_numpy import vol2npy
    from pytom.basic.files import read_em, write_em
    from pytom.basic.functions import taper_edges
    from pytom.basic.transformations import general_transform2d
    from pytom.basic.fourier import ifft, fft
    from pytom.basic.filter import filter as filterFunction, bandpassFilter
    from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, rotateFilter
    from pytom_volume import complexRealMult, vol
    import pytom_freqweight
    from pytom.basic.transformations import resize
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatypeAR
    import os

    if binning:
        imdim = int(float(TiltSeries_._imdim) / float(binning) + .5)
    else:
        imdim = TiltSeries_._imdim
    print('imdim', imdim)

    sliceWidth = imdim

    # pre-determine analytical weighting function and lowpass for speedup
    if (weighting != None) and (weighting < -0.001):
        w_func = fourierFilterShift(rampFilter(imdim, imdim))
    print('start weighting')
    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")
        # weighting filter: arguments: (angle, cutoff radius, dimx, dimy,
        lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim / 2, imdim,
                                      imdim // 2 + 1, 1,
                                      lowpassFilter / 5. * imdim)
        #lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2),
        #                     bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1]

    tilt_angles = []

    for projection in TiltSeries_._ProjectionList:
        tilt_angles.append(projection._tiltAngle)
    tilt_angles = sorted(tilt_angles)
    print(tilt_angles)
    #q = numpy.matrix(abs(numpy.arange(-imdim//2, imdim//2)))

    alignmentResults = numpy.zeros((len(TiltSeries_._ProjectionList)),
                                   dtype=datatypeAR)
    alignmentResults['TiltAngle'] = tilt_angles

    for (ii, projection) in enumerate(TiltSeries_._ProjectionList):

        alignmentResults['FileName'][ii] = os.path.join(
            os.getcwd(), projection._filename)
        transX = -projection._alignmentTransX / binning
        transY = -projection._alignmentTransY / binning
        rot = -(projection._alignmentRotation + 90.)
        mag = projection._alignmentMagnification

        alignmentResults['AlignmentTransX'][ii] = transX
        alignmentResults['AlignmentTransY'][ii] = transY
        alignmentResults['InPlaneRotation'][ii] = rot
        alignmentResults['Magnification'][ii] = mag

        if write_images:
            if projection._filename.split('.')[-1] == 'st':
                from pytom.basic.files import EMHeader, read
                header = EMHeader()
                header.set_dim(x=imdim, y=imdim, z=1)
                idx = projection._index
                if verbose:
                    print("reading in projection %d" % idx)
                image = read(file=projection._filename,
                             subregion=[
                                 0, 0, idx - 1, TiltSeries_._imdim,
                                 TiltSeries_._imdim, 1
                             ],
                             sampling=[0, 0, 0],
                             binning=[0, 0, 0])
                if not (binning == 1) or (binning == None):
                    image = resize(volume=image, factor=1 / float(binning))[0]
            else:
                # read projection files
                from pytom.basic.files import EMHeader, read, read_em_header
                print(projection._filename)
                image = read(projection._filename)
                image = resize(volume=image, factor=1 / float(binning))[0]

                if projection._filename[-3:] == '.em':
                    header = read_em_header(projection._filename)
                else:
                    header = EMHeader()
                    header.set_dim(x=imdim, y=imdim, z=1)

            if lowpassFilter:
                filtered = filterFunction(volume=image,
                                          filterObject=lpf,
                                          fourierOnly=False)
                image = filtered[0]
            tiltAngle = projection._tiltAngle
            header.set_tiltangle(tiltAngle)
            # normalize to contrast - subtract mean and norm to mean
            immean = vol2npy(image).mean()
            image = (image - immean) / immean
            # smoothen borders to prevent high contrast oscillations
            image = taper_edges(image, imdim // 30)[0]
            # transform projection according to tilt alignment

            if projection._filename.split('.')[-1] == 'st':
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.em')
            else:
                TiltSeries_._tiltSeriesFormat = 'mrc'
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.' +
                               TiltSeries_._tiltSeriesFormat)
            if verbose:
                tline = ("%30s" % newFilename)
                tline = tline + (" (tiltAngle=%6.2f)" % tiltAngle)
                tline = tline + (": transX=%6.1f" % transX)
                tline = tline + (", transY=%6.1f" % transY)
                tline = tline + (", rot=%6.2f" % rot)
                tline = tline + (", mag=%5.4f" % mag)
                print(tline)

            image = general_transform2d(v=image,
                                        rot=rot,
                                        shift=[transX, transY],
                                        scale=mag,
                                        order=[2, 1, 0],
                                        crop=True)

            # smoothen once more to avoid edges
            image = taper_edges(image, imdim // 30)[0]

            # analytical weighting
            if (weighting != None) and (weighting < 0):
                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))

            elif (weighting != None) and (weighting > 0):
                if abs(weighting - 2) < 0.001:
                    w_func = fourierFilterShift(
                        rotateFilter(tilt_angles, tiltAngle, imdim, imdim,
                                     sliceWidth))
                else:
                    w_func = fourierFilterShift(
                        exactFilter(tilt_angles, tiltAngle, imdim, imdim,
                                    sliceWidth))

                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))
            header.set_tiltangle(tilt_angles[ii])

            if newFilename.endswith('.mrc'):
                data = copy.deepcopy(vol2npy(image))
                mrcfile.new(newFilename,
                            data.T.astype(float32),
                            overwrite=True)
            else:
                write_em(filename=newFilename, data=image, header=header)

            if verbose:
                tline = ("%30s written ..." % newFilename)

    outname = os.path.join(os.path.dirname(TiltSeries_._alignedTiltSeriesName),
                           'alignmentResults.txt')
    numpy.savetxt(outname,
                  alignmentResults,
                  fmt=fmtAR,
                  header=headerAlignmentResults)
    print('Alignment successful. See {} for results.'.format(outname))
Beispiel #5
0
def toProjectionStackFromAlignmentResultsFile(alignmentResultsFile,
                                              weighting=None,
                                              lowpassFilter=0.9,
                                              binning=1,
                                              circleFilter=False,
                                              num_procs=1,
                                              outdir='',
                                              prefix='sorted_aligned'):
    """read image and create aligned projection stack, based on the results described in the alignmentResultFile.

       @param alignmentResultsFile: result file generate by the alignment script.
       @type datatypeAR: gui.guiFunction.datatypeAR
       @param weighting: weighting (<0: analytical weighting, >1: exact weighting, 0/None: no weighting )
       @type weighting: float
       @param lowpassFilter: lowpass filter (in Nyquist)
       @type lowpassFilter: float
       @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc.

       @author: GvdS
    """
    print('weighting: ', weighting)
    import numpy
    from pytom_numpy import vol2npy
    from pytom.basic.files import read_em, write_em
    from pytom.basic.functions import taper_edges
    from pytom.basic.transformations import general_transform2d
    from pytom.basic.fourier import ifft, fft
    from pytom.basic.filter import filter as filterFunction, bandpassFilter
    from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, \
        fourierFilterShift_ReducedComplex
    from pytom_volume import complexRealMult, vol, paste
    import pytom_freqweight
    from pytom.basic.transformations import resize, rotate
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatype, datatypeAR, loadstar
    from pytom.reconstruction.reconstructionStructures import Projection, ProjectionList
    from pytom_numpy import vol2npy
    import mrcfile
    from pytom.tompy.io import write, read_size
    import os

    print("Create aligned images from alignResults.txt")

    alignmentResults = loadstar(alignmentResultsFile, dtype=datatypeAR)
    imageList = alignmentResults['FileName']
    tilt_angles = alignmentResults['TiltAngle']

    imdim = int(read_size(imageList[0], 'x'))

    if binning > 1:
        imdim = int(float(imdim) / float(binning) + .5)
    else:
        imdim = imdim

    sliceWidth = imdim

    # pre-determine analytical weighting function and lowpass for speedup
    if (weighting != None) and (float(weighting) < -0.001):
        weightSlice = fourierFilterShift(rampFilter(imdim, imdim))

    if circleFilter:
        circleFilterRadius = imdim // 2
        circleSlice = fourierFilterShift_ReducedComplex(
            circleFilter(imdim, imdim, circleFilterRadius))
    else:
        circleSlice = vol(imdim, imdim // 2 + 1, 1)
        circleSlice.setAll(1.0)

    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")
        # weighting filter: arguments: (angle, cutoff radius, dimx, dimy,
        lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim // 2, imdim,
                                      imdim // 2 + 1, 1,
                                      lowpassFilter / 5. * imdim)
        # lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2),
        #                     bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1]

    projectionList = ProjectionList()
    imageList = []
    tilt_angles = []
    for n, image in enumerate(alignmentResults['FileName']):
        atx = alignmentResults['AlignmentTransX'][n]
        aty = alignmentResults['AlignmentTransY'][n]
        rot = alignmentResults['InPlaneRotation'][n]
        mag = alignmentResults['Magnification'][n]
        # print(image, alignmentResults['TiltAngle'][n])
        # if abs(alignmentResults['TiltAngle'][n]) > 20:
        #     continue
        tilt_angles.append(alignmentResults['TiltAngle'][n])
        imageList.append(image)
        projection = Projection(imageList[-1],
                                tiltAngle=tilt_angles[-1],
                                alignmentTransX=atx,
                                alignmentTransY=aty,
                                alignmentRotation=rot,
                                alignmentMagnification=mag)
        projectionList.append(projection)

    stack = vol(imdim, imdim, len(imageList))
    stack.setAll(0.0)

    phiStack = vol(1, 1, len(imageList))
    phiStack.setAll(0.0)

    thetaStack = vol(1, 1, len(imageList))
    thetaStack.setAll(0.0)

    offsetStack = vol(1, 2, len(imageList))
    offsetStack.setAll(0.0)

    for (ii, projection) in enumerate(projectionList):
        if projection._filename.split('.')[-1] == 'st':
            from pytom.basic.files import EMHeader, read
            idx = projection._index
            image = read(file=projection._filename,
                         subregion=[0, 0, idx - 1, imdim, imdim, 1],
                         sampling=[0, 0, 0],
                         binning=[0, 0, 0])
            if not (binning == 1) or (binning == None):
                image = resize(volume=image, factor=1 / float(binning))[0]
        else:
            # read projection files
            from pytom.basic.files import EMHeader, read, read_em_header
            image = read(str(projection._filename))
            # image = rotate(image,180.,0.,0.)
            image = resize(volume=image, factor=1 / float(binning))[0]

        if lowpassFilter:
            filtered = filterFunction(volume=image,
                                      filterObject=lpf,
                                      fourierOnly=False)
            image = filtered[0]

        tiltAngle = projection._tiltAngle

        # normalize to contrast - subtract mean and norm to mean
        immean = vol2npy(image).mean()
        image = (image - immean) / immean

        print(ii, immean, projection._filename)

        # smoothen borders to prevent high contrast oscillations
        image = taper_edges(image, imdim // 30)[0]

        # transform projection according to tilt alignment
        transX = projection._alignmentTransX / binning
        transY = projection._alignmentTransY / binning
        rot = float(projection._alignmentRotation)
        mag = float(projection._alignmentMagnification)

        image = general_transform2d(v=image,
                                    rot=rot,
                                    shift=[transX, transY],
                                    scale=mag,
                                    order=[2, 1, 0],
                                    crop=True)

        # smoothen once more to avoid edges
        image = taper_edges(image, imdim // 30)[0]

        # analytical weighting
        if (weighting != None) and (weighting < 0):
            # image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ()))
            image = ifft(complexRealMult(
                complexRealMult(fft(image), weightSlice), circleSlice),
                         scaling=True)

        elif (weighting != None) and (weighting > 0):
            weightSlice = fourierFilterShift(
                exactFilter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth))
            # image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ()))
            image = ifft(complexRealMult(
                complexRealMult(fft(image), weightSlice), circleSlice),
                         scaling=True)

        thetaStack(int(round(projection.getTiltAngle())), 0, 0, ii)
        offsetStack(int(round(projection.getOffsetX())), 0, 0, ii)
        offsetStack(int(round(projection.getOffsetY())), 0, 1, ii)
        paste(image, stack, 0, 0, ii)
        fname = '{}_{:02d}.mrc'.format(
            prefix, int(imageList[ii].split('_')[-1].split('.')[0]))
        if outdir:
            import mrcfile
            # write_em(os.path.join(outdir, fname.replace('mrc', 'em')), image)
            write(os.path.join(outdir, fname),
                  vol2npy(image).copy().astype('float32'))
            print('written file: ', fname)

    return [stack, phiStack, thetaStack, offsetStack]
Beispiel #6
0
    def setUp(self):

        from pytom.basic.functions import initSphere
        from pytom.image2D.imageStructures import ImageStack, Image
        from pytom.basic.transformations import general_transform2d
        import pytom.simulation.whiteNoise
        import random

        random.seed(0)
        self.dim = 32
        self.nim = 41
        self.snr = .1
        self.radius = 7.

        self.sph = initSphere(sizeX=self.dim,
                              sizeY=self.dim,
                              sizeZ=1,
                              radius=self.radius,
                              smooth=1.,
                              maxradius=0,
                              cent=None,
                              filename='')
        self.imageStack = ImageStack()

        # random shift
        self.shiftX = []
        self.shiftY = []
        sumX = 0.
        sumY = 0.
        for ii in range(0, self.nim):
            self.shiftX.append(random.gauss(mu=0., sigma=2.))
            self.shiftY.append(random.gauss(mu=0., sigma=2.))
        sumX = sumX / self.nim
        sumY = sumY / self.nim
        for ii in range(0, self.nim):
            self.shiftX[ii] = self.shiftX[ii] - sumX
            self.shiftY[ii] = self.shiftY[ii] - sumY

        # apply shifts
        for ii in range(0, self.nim):
            image = Image(filename=None,
                          boxCoords=[0, 0, 0],
                          dims=[self.dim, self.dim, 1],
                          shiftX=0,
                          shiftY=0,
                          appliedShiftX=0,
                          appliedShiftY=0,
                          rotation=0,
                          index=ii,
                          verbose=False)
            tmp = general_transform2d(v=self.sph,
                                      rot=0.,
                                      shift=[self.shiftX[ii], self.shiftY[ii]],
                                      scale=1.,
                                      order=[2, 1, 0],
                                      crop=True)
            image.data = pytom.simulation.whiteNoise.add(volume=tmp,
                                                         SNR=self.snr)
            self.imageStack.append(image=image)

        self.imageStack.normalize(normtype="StdMean")
        self.imageStack.bandpass(lowfreq=1., hifreq=6., smooth=2., bpf=None)
        # smoothen edges
        self.imageStack.taper_edges(width=self.dim / 8.)

        self.imageStack.exMaxAlign(niter=10, mask=None)
        self.imageStack.write('input.em')
        self.imageStack.writeWorkingCopies('output.em')