예제 #1
0
def plot_FSC(FSCFile, pixelsize, boxsize=0, outname='',show_image=True, c=0.143):
    data = numpy.array(list(map(float, loadstar(FSCFile))))
    dim  = len(data)
    if not boxsize: 
        boxsize = dim
        print('Boxsize set to dimension of FSC data ({})'.format(boxsize))
    x = numpy.arange(dim)*(1/(float(pixelsize)*int(boxsize)))

    fig, ax = subplots(1,1,figsize=(5,3))

    ax.plot( x, data,color='#1989ac',lw=2, label=os.path.basename(FSCFile))

    ax.set_xticks([0,x[dim//4],x[dim//2],x[3*dim//4],x[-1]])
    ax.set_xticklabels(['',1/x[dim//4]//1,1/x[dim//2]//1,1/x[3*dim//4]//1,1/x[-1]//1])
    ax.set_ylabel('Correlation Coefficient' )
    ax.set_xlabel(r'resolution ($\AA$)') 
    if c:
        ax.hlines(c,0,x[-1],lw=1,colors='#54d777', label='Cut off')
    ax.legend()
    ax.set_yticks([ 0, 0.25, 0.5, 0.75, 1])
    ax.set_yticklabels([0,0.25,0.5,0.75,1])
    fig.tight_layout()
    if outname: 
        savefig(outname)
    if show_image: 
        show()
예제 #2
0
def readPolishResultFile(filename, tilt_angles=None, non_stacked=False):
    try:
        from pytom.gui.guiFunctions import LOCAL_ALIGNMENT_RESULTS, loadstar

        ppf = loadstar(filename, dtype=LOCAL_ALIGNMENT_RESULTS)
        if non_stacked:
            return ppf
        num = ppf['ParticleIndex'][-1] + 1
        rppf = ppf.reshape(num, ppf.shape[0] // num)

        if not tilt_angles is None:
            polishangles = rppf[0]['TiltAngle']
            polishIndices = []
            for angle in tilt_angles:
                for n, pangle in enumerate(polishangles):
                    if abs(pangle - angle) < 0.01:
                        polishIndices.append(n)
                        break

            if len(polishIndices) != len(self):
                print(self.tilt_angles)
                print(polishIndices)
                raise Exception(
                    'data from polishfile does not contain the same angles as the angles from tiltimages'
                )

        polishResults = rppf

    except Exception as e:
        print(e)
        raise Exception(
            'data from polishfile does not contain the same angles as the angles from tiltimages'
        )

    return polishResults
예제 #3
0
def readMarkerfile(filename, num_tilt_images=0):
    if filename.endswith('.em'):
        from pytom.basic.files import read
        from pytom_numpy import vol2npy
        markerfile = read(filename)
        markerdata = vol2npy(markerfile).copy()
        return markerdata

    elif filename.endswith('.txt'):
        data = loadstar(filename)
        datalen = data.shape[0]
        num_tilt_images = (data[:, 0] == data[0, 0]).sum()
        x, y = datalen // num_tilt_images, num_tilt_images
        markerdata = data.reshape(x, y, 4)[:, :, 1:].transpose(2, 1, 0)
        return markerdata
예제 #4
0
def CorrectTiltseries(metafile,
                      uprefix,
                      cprefix,
                      gs,
                      fs,
                      binning_factor,
                      rotation_angle,
                      def_grad_strip=2.5):
    """
    This function corrects the astigmatic defocus gradient of a tiltseries.

    INPUT
    dz1 --- defocus of tiltseries first principal component
    dz2 --- defocus of tiltseries second principal component
    alpha --- astigmatism angle
    alg --- alignment parameter of the tiltseries
    PathTS --- path of tiltseries
    NameTS --- name of projections of tiltseries
    PathTScor --- path of the corrected tiltseries
    NameTScor --- name of the projections of the corrected tiltseries
    gs --- grid spacing /in pixel
    fs --- fieldsize /in pixel
    Objectpixelsize --- /in nm
    Voltage --- /in kV
    Cs --- /in mm
    Amplitude/Phase ratio

    OUTPUT
    CTF corrected tiltseries
    """

    # NumOfProj
    import glob
    from pytom.gui.guiFunctions import loadstar

    fnames = [line for line in sorted(glob.glob(uprefix + "*"))]

    NumOfProj = len(glob.glob(uprefix + "*"))
    args = []
    metadata = loadstar(metafile, dtype=datatype)

    for p, fname in enumerate(fnames):
        # Corrected projection name
        new_fname = cprefix + os.path.basename(fname).split("_")[-1]

        #args.append((fname, new_fname, p, metafile, gs, fs, binning_factor, rotation_angle))
        CorrectProjection_proxy(fname, new_fname, p, metadata, gs, fs,
                                binning_factor, rotation_angle, def_grad_strip)
예제 #5
0
def txt2markerfile(filename, tiltangles):
    data = loadstar(filename)
    datalen = data.shape[0]
    num_angles = (data[:, 0] < 1E-6).sum()
    if num_angles == len(tiltangles):
        x, y = datalen // len(tiltangles), len(tiltangles)
        mark_frames = data.reshape(x, y, 4)[:, :, 2:].transpose(1, 0, 2)
        print(mark_frames.shape)
        return mark_frames
    else:
        x, y = datalen // num_angles, num_angles
        mark_frames_small = data.reshape(x, y, 4)[:, :, 2:].transpose(1, 0, 2)
        mark_frames = -1 * numpy.ones(
            (len(tiltangles), x, 2), dtype=numpy.float32)
        ang_selected = data[:num_angles, 1]
        runner = 0
        for n, angle in enumerate(tiltangles):
            if numpy.abs(ang_selected - angle).min() < 1E-5:
                mark_frames[n, :, :] = mark_frames_small[runner, :, :]
                runner += 1

        return mark_frames
예제 #6
0
def update_metafile(filename, columnID, values):
    metadata = loadstar(filename, dtype=datatype)
    metadata[columnID] = values
    savestar(filename, metadata, fmt=fmt, header=headerText)
예제 #7
0
def parseImodShiftFile(imodShiftFile):

    data = loadstar(imodShiftFile)
    return data[:, -2:]
예제 #8
0
def update_metadata_from_defocusfile(metafile, defocusfile):
    metadata = loadstar(metafile, dtype=datatype)

    data = open(defocusfile, 'r')
    header = list(map(float, data.readlines()[0].split()))
    skiprows = 0

    for h in header[2:-1]:
        if abs(h) < 0.001:
            skiprows = 1

    data.close()

    if skiprows:
        print('First Line of {} is ignorned'.format(
            os.path.basename(defocusfile)))

    for dd in (10, 9, 8, 7, 6, 5):
        try:
            defocusResults = loadstar(defocusfile,
                                      skip_header=skiprows,
                                      usecols=range(0, dd))
        except:
            continue
        break

    if len(defocusResults) > len(metadata):
        raise Exception(
            'Defocus file is larger than meta file thus cannot uniquely determine all angles.'
        )

    tiltImages, columns = defocusResults.shape

    resultsNames = [
        'ID_start', 'ID_end', 'AngleStart', 'AngleEnd', 'DefocusU', 'DefocusV',
        'DefocusAngle', 'PhaseShift', 'CutOn'
    ]
    if columns < 6 or defocusResults[0][5] < 400:
        resultsNames[5] = 'Empty'
        resultsNames[6] = 'Empty'
        columns += 2
    resultsNames = resultsNames[:columns]

    for n, line in enumerate(defocusResults):
        angleN = line[2]

        NN = 999
        for index, j in enumerate(metadata['TiltAngle']):
            if abs(j - angleN) < 0.1:
                NN = index
        if NN > 900:
            angleN = (line[2] + line[3]) / 2.
            for index, j in enumerate(metadata['TiltAngle']):
                if abs(j - angleN) < 0.1:
                    NN = index
        if NN > 900:
            raise Exception(
                'Angles from Defocus File does not correspond to angles in metafile.'
            )

        for query in ('DefocusU', 'DefocusV', 'DefocusAngle', 'PhaseShift'):
            for nn, ii in enumerate(resultsNames):
                if query == ii:
                    metadata[query][NN] = line[nn]
                    if query in ('DefocusU', 'DefocusV'):
                        metadata[query][NN] /= 1000.
                    break
        if 'Empty' in resultsNames:
            metadata['DefocusV'][NN] = metadata['DefocusU'][NN]
            metadata['DefocusAngle'][NN] = 0.

    savestar(metafile, metadata, fmt=fmt, header=headerText)
예제 #9
0
def CorrectProjection_proxy(fname, new_fname, p, metafile, gs, fs,
                            binning_factor, rotation_angle):
    """
    @param fname: filename
    @type fname: C{str}
    @param new_fname:
    @type new_fname: C{str}
    @param p:
    @param metafile: star-file with metadata (contains defoci (long-/short), astig agnle alpha, 
                     voltage, Cs, Amplitude-contrast, Imdim, PixelSpacing, Magnification
    @type metafile: C{str}
    @param gs: grid spacing [2,4,6,...] is the size of the area which is
               corrected with a constant ctf. The ctf value is taken
               from the center of this area. This area builds up the
               corrected projection.
    @param fs: fieldsize [2,4,6,...] & (fs>=gs) is the size of the area which
               is extracted from the projection and corrected with a
               constant ctf. Fieldsize is also the size of the modelled ctf.
    @param binning_factor: de-magnfication factor
    @type binning_factor: C{float}
    @param rotation_angle:
    @return:

    """
    print('Correct projection:', fname)

    # load the metadata
    #from numpy import loadtxt
    from pytom.gui.guiFunctions import loadstar
    metadata = loadstar(metafile, dtype=datatype)

    # Alignment parameter
    Tiltangles = metadata['TiltAngle']
    Tiltaxis = rotation_angle
    directions = {0: 'horizontal', 1: 'vertical'}
    direction = directions[int(np.around(Tiltaxis / 90)) % 2]

    dz1 = metadata['DefocusU']
    dz2 = metadata['DefocusV']
    alpha = metadata['DefocusAngle']

    Voltage = metadata['Voltage'][p]
    Cs = metadata['SphericalAberration'][p]
    A = metadata['AmplitudeContrast'][p]
    Imdim = metadata['ImageSize'][p]

    if Imdim == 0: Imdim = 3710

    Objectpixelsize = metadata['PixelSpacing'][p] * 0.1 * binning_factor

    from pytom.tompy.io import read, write

    # Load projection
    proj = np.array(read(fname))
    proj = np.squeeze(proj)  # squeeze it to 2D

    # Create defocus plane dz1
    dz1p = CalculateDefocusModel(dz1[p], Objectpixelsize, Imdim, Tiltangles[p],
                                 Tiltaxis)

    # Create defocus plane dz2
    dz2p = CalculateDefocusModel(dz2[p], Objectpixelsize, Imdim, Tiltangles[p],
                                 Tiltaxis)

    # Create astigmatism angle plane
    alphap = (alpha[p] + Tiltaxis) * np.ones((Imdim, Imdim))

    # !!! ADDED Tiltaxis(1,p) to astigmatsm angle to correct for Tiltaxis rotation during CTF determination !!! -- SP 7.7.16
    # originally: alphap = alpha[p]*np.ones((Imdim,Imdim))

    projc = CorrectProjection(proj,
                              dz1p,
                              dz2p,
                              alphap,
                              gs,
                              fs,
                              Objectpixelsize,
                              Voltage,
                              Cs,
                              A,
                              direction=direction)

    # Save projection
    try:
        mrcfile.new(new_fname, projc.T.get(), overwrite=True)
    except:
        mrcfile.new(new_fname, projc.T, overwrite=True)

    #write(new_fname, projc, Tiltangles[p])

    return True
예제 #10
0
def extractParticleListsClosestToRefMarker(xmlfile,
                                           markerfile,
                                           binning_factor=8,
                                           directory='./',
                                           projDirTemplate=''):
    from pytom.basic.structures import PickPosition, ParticleList
    pL = ParticleList()
    pL.fromXMLFile(os.path.join(directory, xmlfile))

    dict_particle_lists = {}

    for particle in pL:
        tomogram = particle.getPickPosition().getOriginFilename().split(
            '/')[-1].split('.')[0]
        if not tomogram:
            tomogram = particle.getSourceInfo().getTomoName().split('.')[0]
        if not tomogram in dict_particle_lists.keys():
            dict_particle_lists[tomogram] = ParticleList()
        dict_particle_lists[tomogram].append(particle)

    try:
        markers = loadstar(markerfile, dtype=datatypeMR)
    except:
        correct_header_markerfile(markerfile)
        markers = loadstar(markerfile, dtype=datatypeMR)

    xmlsCM = []

    for pl_key in dict_particle_lists.keys():
        outLists = {}
        for particle in dict_particle_lists[pl_key]:
            x, y, z = particle.getPickPosition().toVector()
            x *= binning_factor
            y *= binning_factor
            z *= binning_factor

            closestMarkerIndex = determine_closest_marker(x, y, z, markers)
            projectionDirectory = projDirTemplate.replace(
                '_CLOSEST_', '_{:04d}_'.format(closestMarkerIndex))
            markerPositionFile = f'{projectionDirectory}/markerLocations_irefmark_{closestMarkerIndex}.txt'

            realignmarkers = loadstar(markerPositionFile, dtype=datatypeMR)

            if not closestMarkerIndex in outLists.keys():
                outLists[closestMarkerIndex] = ParticleList()

            ox, oy = determineShiftXY(markers, realignmarkers)

            oz = markers['OffsetZ'][closestMarkerIndex]
            originFname = particle.getPickPosition().getOriginFilename()

            print(x, y, z, ox, oy, oz)
            pp = PickPosition(x=(x - ox) / binning_factor,
                              y=(y - oy) / binning_factor,
                              z=((z - oz) / binning_factor),
                              originFilename=originFname)
            particle.setPickPosition(pp)
            outLists[closestMarkerIndex].append(particle)

        for markerIndex in outLists.keys():
            outfname = '.tempCM_particleList_{}_refMarkerIndex_{}.xml'.format(
                pl_key, markerIndex)
            outfname = os.path.join(directory, outfname)
            outLists[markerIndex].toXMLFile(outfname)
            xmlsCM.append([markerIndex, outfname])

    return xmlsCM
예제 #11
0
            sys.argv[1:], helper)
    except Exception as e:
        print(e)
        sys.exit()
    if b_help is True:
        print(helper)
        sys.exit()

    # parse the arguments
    if not iter:
        iter = 10
    else:
        iter = int(iter)

    if metafile and os.path.exists(metafile):
        metadata = loadstar(metafile, dtype=datatype)
        tiltAngles = metadata['TiltAngle']
    else:
        tiltAngles = []

    metafile = '' if metafile is None or not os.path.exists(
        metafile) else metafile

    # start reconstruction
    from pytom.tompy.io import read, write
    from nufft.reconstruction import fourier_2d1d_iter_reconstruct
    from pytom.reconstruction.reconstructionStructures import ProjectionList
    projections = ProjectionList()
    projections.loadDirectory(proj_dir, metafile=metafile)
    projections.sort()
예제 #12
0
                '-s', '--sizeReconstruction'
            ], 'Size Reconstruction in pixels. Three numbers separated by a comma.',
                         True, True),
            ScriptOption(['-v', '--verbose'], 'print intermediate output',
                         False, True)
        ])
    try:
        proj_dir, outdir, coordinateBinning, gpu, metafile, alignmentfile, size, verbose = ll = parse_script_options(
            sys.argv[1:], helper)
    except Exception as e:
        print(e)
        print(helper)
        sys.exit()

    coordinateBinning = int(coordinateBinning) if coordinateBinning else 1
    metadata = loadstar(metafile, dtype=DATATYPE_METAFILE)
    tilt_angles = metadata['TiltAngle']
    size = [464, 464, 464] if size is None else list(map(int, size.split(',')))
    patches = xp.zeros((size[0], size[1], len(tilt_angles)), dtype=xp.float32)

    images = []

    tt = time()

    cur = 0
    missed = 0
    for i in range(patches.shape[2]):
        temp_image = alignImageUsingAlignmentResultFile(
            alignmentfile,
            i,
            weighting=-1,
예제 #13
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]
예제 #14
0
def alignImagesUsingAlignmentResultFile(alignmentResultsFile,
                                        weighting=None,
                                        lowpassFilter=0.9,
                                        binning=1,
                                        circleFilter=False):
    import os
    from pytom.basic.files import read as readCVol
    from pytom_numpy import vol2npy, npy2vol
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatype, datatypeAR, loadstar
    from pytom.reconstruction.reconstructionStructures import Projection, ProjectionList
    from pytom.tompy.io import read, write, read_size
    from pytom.tompy.tools import taper_edges, create_circle
    from pytom.tompy.filter import circle_filter, ramp_filter, exact_filter
    import pytom.voltools as vt
    from pytom.gpu.initialize import xp, device
    print("Create aligned images from alignResults.txt")

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

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

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

    sliceWidth = imdim

    if (weighting != None) and (float(weighting) < -0.001):
        weightSlice = xp.fft.fftshift(ramp_filter(imdim, imdim))

    if circleFilter:
        circleFilterRadius = imdim // 2
        circleSlice = xp.fft.fftshift(
            circle_filter(imdim, imdim, circleFilterRadius))
    else:
        circleSlice = xp.ones((imdim, imdim))

    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")

        # weighting filter: arguments: (()dimx, dimy), cutoff radius, sigma
        lpf = xp.fft.fftshift(
            create_circle((imdim, imdim),
                          lowpassFilter * (imdim // 2),
                          sigma=0.4 * lowpassFilter * (imdim // 2)))

    projectionList = ProjectionList()
    for n, image in enumerate(imageList):
        atx = alignmentResults['AlignmentTransX'][n] / binning
        aty = alignmentResults['AlignmentTransY'][n] / binning
        rot = alignmentResults['InPlaneRotation'][n]
        mag = 1 / alignmentResults['Magnification'][n]
        projection = Projection(imageList[n],
                                tiltAngle=tilt_angles[n],
                                alignmentTransX=atx,
                                alignmentTransY=aty,
                                alignmentRotation=rot,
                                alignmentMagnification=mag)
        projectionList.append(projection)

    stack = xp.zeros((imdim, imdim, len(imageList)), dtype=xp.float32)
    phiStack = xp.zeros((1, 1, len(imageList)), dtype=xp.float32)
    thetaStack = xp.zeros((1, 1, len(imageList)), dtype=xp.float32)
    offsetStack = xp.zeros((1, 2, len(imageList)), dtype=xp.float32)

    for (ii, projection) in enumerate(projectionList):
        print(f'Align {projection._filename}')
        image = read(str(projection._filename))[::binning, ::binning].squeeze()

        if lowpassFilter:
            image = xp.abs((xp.fft.ifftn(xp.fft.fftn(image) * lpf)))

        tiltAngle = projection._tiltAngle

        # normalize to contrast - subtract mean and norm to mean
        immean = 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
        transX = projection._alignmentTransX / binning
        transY = projection._alignmentTransY / binning
        rot = float(projection._alignmentRotation)
        mag = float(projection._alignmentMagnification)

        inputImage = xp.expand_dims(image, 2).copy()
        outputImage = xp.zeros_like(inputImage, dtype=xp.float32)

        vt.transform(inputImage.astype(xp.float32),
                     rotation=[0, 0, rot],
                     rotation_order='rxyz',
                     output=outputImage,
                     device=device,
                     translation=[transX, transY, 0],
                     scale=[mag, mag, 1],
                     interpolation='filt_bspline')

        image = outputImage.squeeze()

        # 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 = xp.fft.ifftn(
                xp.fft.fftn(image) * weightSlice * circleSlice)

        elif (weighting != None) and (weighting > 0):
            weightSlice = xp.fft.fftshift(
                exact_filter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth))
            image = xp.fft.ifftn(
                xp.fft.fftn(image) * weightSlice * circleSlice)

        thetaStack[0, 0, ii] = int(round(projection.getTiltAngle()))
        offsetStack[0, :, ii] = xp.array([
            int(round(projection.getOffsetX())),
            int(round(projection.getOffsetY()))
        ])

        stack[:, :, ii] = image

    arrays = []

    for fname, arr in (('stack.mrc', stack), ('offsetStack.mrc', offsetStack),
                       ('thetaStack.mrc', thetaStack), ('phiStack.mrc',
                                                        phiStack)):
        if 'gpu' in device:
            arr = arr.get()
        import numpy as np
        res = npy2vol(np.array(arr, dtype='float32', order='F'), 3)
        arrays.append(res)

    #
    #     write('stack.mrc', stack)
    #     stack = readCVol('stack.mrc')
    # write('offsetstack.mrc', offsetStack)
    # offsetStack = readCVol('offsetstack.mrc')
    # write('thetastack.mrc', thetaStack)
    # thetaStack = readCVol('thetastack.mrc')
    # write('phistack.mrc', phiStack)
    # phiStack = readCVol('phistack.mrc')
    #
    # os.remove('stack.mrc')
    # os.remove('offsetstack.mrc')
    # os.remove('thetastack.mrc')
    # os.remove('psistack.mrc')

    return arrays
예제 #15
0
def alignImageUsingAlignmentResultFile(alignmentResultsFile,
                                       indexImage,
                                       weighting=None,
                                       lowpassFilter=0.9,
                                       binning=1,
                                       circleFilter=False):
    import pytom_freqweight
    from pytom_numpy import vol2npy
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatype, datatypeAR, loadstar
    from pytom.reconstruction.reconstructionStructures import Projection, ProjectionList
    from pytom.tompy.io import read, write, read_size
    from pytom.tompy.tools import taper_edges, create_circle
    from pytom.tompy.filter import circle_filter, ramp_filter, exact_filter, ellipse_filter
    import pytom.voltools as vt
    from pytom.gpu.initialize import xp, device

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

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

    imdimX = read_size(imageList[0], 'x')
    imdimY = read_size(imageList[0], 'y')

    if binning > 1:
        imdimX = int(float(imdimX) / float(binning) + .5)
        imdimY = int(float(imdimY) / float(binning) + .5)

    sliceWidth = imdimX

    if (weighting != None) and (float(weighting) < -0.001):
        weightSlice = xp.fft.fftshift(ramp_filter(imdimY, imdimX))

    if circleFilter:
        circleFilterRadiusX = imdimX // 2
        circleFilterRadiusY = imdimY // 2

        circleSlice = xp.fft.fftshift(
            ellipse_filter(imdimX, imdimY, circleFilterRadiusX,
                           circleFilterRadiusY))
    else:
        circleSlice = xp.ones((imdimX, imdimY))

    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")

        # weighting filter: arguments: (()dimx, dimy), cutoff radius, sigma
        # lpf = xp.fft.fftshift(create_circle((imdimX,imdimY),lowpassFilter*(imdim//2), sigma=0.4*lowpassFilter*(imdim//2)))

    projectionList = ProjectionList()
    for n, image in enumerate(imageList):
        atx = alignmentResults['AlignmentTransX'][n]
        aty = alignmentResults['AlignmentTransY'][n]
        rot = alignmentResults['InPlaneRotation'][n]
        mag = 1 / (alignmentResults['Magnification'][n])
        projection = Projection(imageList[n],
                                tiltAngle=tilt_angles[n],
                                alignmentTransX=atx,
                                alignmentTransY=aty,
                                alignmentRotation=rot,
                                alignmentMagnification=mag)
        projectionList.append(projection)

    imdim = min(imdimY, imdimX)

    for (ii, projection) in enumerate(projectionList):
        if not ii == indexImage:
            continue
        from pytom.tompy.transform import resize

        # print(f'read {projection._filename}')
        image = read(str(projection._filename)).squeeze()

        if binning > 1:
            image = resize(image, 1 / binning)

        #write(f'test/image_{ii}.mrc', image, tilt_angle=tilt_angles[ii])

        tiltAngle = projection._tiltAngle

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

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

        # 3 -- square if needed
        if 0 and imdimY != imdimX:
            newImage = xp.zeros((imdim, imdim, 1), dtype=xp.float32)
            pasteCenter(image, newImage)
            image = newImage

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

        inputImage = xp.expand_dims(image, 2).copy()
        outputImage = xp.zeros_like(inputImage, dtype=xp.float32)

        vt.transform(
            inputImage.astype(xp.float32),
            rotation=[0, 0, rot],
            rotation_order='rxyz',
            output=outputImage,
            center=[inputImage.shape[0] // 2, inputImage.shape[1] // 2, 0],
            device=device,
            translation=[transX, transY, 0],
            scale=[mag, mag, 1],
            interpolation='filt_bspline')

        del image
        image = outputImage.squeeze()

        # 5 -- Optional Low Pass Filter
        if lowpassFilter:
            from pytom.tompy.filter import bandpass_circle

            image = bandpass_circle(
                image,
                high=lowpassFilter * (min(imdimX, imdimY) // 2),
                sigma=0.4 * lowpassFilter * (min(imdimX, imdimY) // 2))
            # image = xp.abs((xp.fft.ifftn(xp.fft.fftn(image) * lpf)))

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

        # 7 -- analytical weighting
        if (weighting != None) and (weighting < 0):

            # image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ()))
            image = xp.fft.ifftn(
                xp.fft.fftn(image) * weightSlice.T * circleSlice).real

        elif (weighting != None) and (weighting > 0):
            weightSlice = xp.fft.fftshift(
                exact_filter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth))
            image = xp.fft.ifftn(
                xp.fft.fftn(image) * weightSlice * circleSlice).real

        del inputImage, outputImage, circleSlice

        write(f'inputImage_{ii}.mrc', image)

        return image.astype(xp.float32)
예제 #16
0
                                            applyWeighting=aw)
        vol.write(tomogram)

    else:
        # transform the cropping offset
        try:
            tmp = projections[0]
            sx = tmp.getXSize(
            )  # here should be the size of original projection!
            sy = tmp.getYSize()
        except:
            from pytom.basic.datatypes import DATATYPE_ALIGNMENT_RESULTS
            from pytom.tompy.io import read_size
            from pytom.gui.guiFunctions import loadstar

            lar = loadstar(alignResultFile, dtype=DATATYPE_ALIGNMENT_RESULTS)
            sx, sy, sz = read_size(lar['FileName'][0])

        # sx, sy = 1024, 1024
        recOffset[0] = -sx / 2 + recOffset[0] * coordinateBinning
        recOffset[1] = -sy / 2 + recOffset[1] * coordinateBinning
        recOffset[2] = -sx / 2 + recOffset[2] * coordinateBinning

        # set particle list in order to reconstruct subtomograms
        particleList = ParticleList()

        try:
            particleList.fromXMLFile(particleListXMLPath)
        except RuntimeError:
            print('Error reading particleList XML file! Abort')
            sys.exit()