Пример #1
0
    def setUp(self):
        from helper_functions import create_RandomParticleList
        from pytom.tompy.io import read_size
        from pytom_volume import vol, initSphere

        self.reffile = './testData/ribo.em'
        self.pl_filename = 'pl.xml'
        self.pdir = './testparticles'
        self.pl = create_RandomParticleList(reffile=self.reffile,
                                            pl_filename=self.pl_filename,
                                            pdir=self.pdir,
                                            nparticles=10)

        # set parameters for GLocal
        self.settings = {}
        self.settings["binning"] = 4
        self.settings["niteration"] = 1
        self.settings["mask"] = './testData/ribo_mask.em'
        dims = read_size(self.reffile)
        maskvol = vol(int(dims[0]), int(dims[1]), int(dims[2]))
        initSphere(maskvol, 30, 5, 0, int(dims[0] / 2), int(dims[1] / 2),
                   int(dims[2] / 2))
        maskvol.write(self.settings["mask"])
        self.settings["destination"] = './'
        #self.settings["score"] = 'nxcf'
        self.settings["score"] = 'flcf'
        self.settings["pixelsize"] = 2.
        self.settings["diameter"] = 250.
        self.settings["job"] = './myGLocal.xml'
Пример #2
0
def get_size(particleList, directory):
    tempPL = ParticleList()
    tempPL.fromXMLFile(particleList)

    tomoName = tempPL[0].getPickPosition().getOriginFilename(
    ) if tempPL[0].getPickPosition().getOriginFilename(
    ) else tempPL[0].getSourceInfo().getTomoName()

    if not os.path.exists(tomoName):
        tomoName = os.path.join(directory, tomoName)
        if not os.path.exists(tomoName):
            return 'Failed'

    try:
        dimx, dimy, dimz = read_size(tomoName)
    except:
        print('Failed')
        return 'Failed'

    return [dimx, dimy, dimz]
Пример #3
0
            ScriptOption(['--metaFile'], 'Metafile containing tiltangles.',
                         True, True),
            ScriptOption(['-v', '--verbose'], 'print intermediate output',
                         False, True)
        ])

    try:
        particleList, proj_dir, template, outdir, fsc_path, coordinateBinning, recOffset, max_shift, \
        create_graphics, number_of_particles, metafile, verbose = ll = parse_script_options(sys.argv[1:], helper)
    except Exception as e:
        print(e)
        print(helper)
        sys.exit()

    print(ll)
    vol_size = read_size(template, 'x')
    if vol_size % 2 != 0:
        raise ValueError("The particle size has to be an even number.")

    coordinateBinning = int(coordinateBinning) if coordinateBinning else 1
    recOffset = list(map(int,
                         recOffset.split(','))) if recOffset else [0, 0, 0]
    max_shift = int(max_shift) if max_shift else 6
    create_graphics = True if create_graphics else False
    number_of_particles = int(
        number_of_particles) if number_of_particles else 0
    peak_border = vol_size // 2 - max_shift
    if peak_border < 0:
        raise ValueError(
            "The given shiftStandardDeviation and peakBorderSize result in a maximal shift "
            "bigger than the given volume. Please use a bigger volume or a smaller maximal shift."
Пример #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, pasteCenter
    import pytom_freqweight
    from pytom.basic.transformations import resize
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatypeAR
    import os
    from pytom.basic.files import EMHeader, read, read_em_header
    from pytom.tompy.io import read_size
    if binning:
        imdim = int(float(TiltSeries_._imdim)/float(binning)+.5)
    else:
        imdim = TiltSeries_._imdim

    imdimX = int(numpy.around(read_size(TiltSeries_._ProjectionList[0]._filename, 'x')/binning,0))
    imdimY = int(numpy.around(read_size(TiltSeries_._ProjectionList[0]._filename, 'y')/binning,0))

    imdim = int(max(imdimX, imdimY))

    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)
        # lpf2 = pytom_freqweight.weight(0.0, lowpassFilter * imdimY / 2, imdimX, imdimY // 2 + 1, 1,
        #                               lowpassFilter / 5. * imdimY)
        #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)

    #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
                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)


            tiltAngle = projection._tiltAngle
            header.set_tiltangle(tiltAngle)

            # # 5 -- Optional Low Pass Filter
            # if lowpassFilter:
            #     filtered = filterFunction( volume=image, filterObject=lpf2, fourierOnly=False)
            #     image = filtered[0]

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


            # 2 -- 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)

            # 3 -- square if needed
            if imdimY != imdimX:
                print('Squared image to larger dimension')
                newImage = vol(imdim, imdim,1)
                newImage.setAll(0)
                pasteCenter(image, newImage)
                image = newImage




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

            # 5 -- Optional Low Pass Filter
            if lowpassFilter:
                filtered = filterFunction( volume=image, filterObject=lpf, fourierOnly=False)
                image = filtered[0]

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

            # 7 -- 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 weighting > 1.5:
                    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))
Пример #5
0
def createMetaDataFiles(nanographfolder,
                        mdocfiles=[],
                        target='',
                        mdoc_only=False):

    if not mdocfiles:
        mdocfiles = [
            mdocfile for mdocfile in os.listdir(nanographfolder)
            if mdocfile.endswith('.mdoc')
        ]
    datafiles = [
        fname for fname in os.listdir(nanographfolder)
        if fname.split('.')[-1] in ('tif', 'mrc', 'em',
                                    'st') and not (fname[0] in '0123456789')
    ]

    annotated = {}

    tomo_from_filename = {}
    tomo_from_stack = {}

    for df in datafiles:
        annotated[os.path.basename(df)] = 0
        if os.path.basename(df).endswith('.st'):
            annotated[os.path.basename(df)] = 'st'

    tiltAxis = 180
    pixelSpacing = 1.5
    voltage = 300

    for nr, mdocfile in enumerate(sorted(mdocfiles)):
        metadata = []
        mdocfilepath = os.path.join(nanographfolder, mdocfile)
        header = False
        datadict = {
            'TiltAngle': tiltAxis,
            'Magnification': 79000,
            'Intensity': 0.0,
            'PixelSpacing': pixelSpacing,
            'Defocus': 3,
            'RotationAngle': 270,
            'SubFramePath': '',
            'Voltage': voltage,
            'MarkerDiameter': 100,
            'SphericalAberration': 2.7,
            'AmplitudeContrast': 0.08,
            'PhaseContrast': 0.,
        }
        for description, dtype in datatype:
            if not description in datadict.keys(): datadict[description] = 0.

        mdocdata = [
            line.split() for line in open(mdocfilepath).readlines()
            if len(line.split()) >= 3
        ]
        nrTiltImages = 0
        for nn, line in enumerate(mdocdata):
            if '[ZValue' == line[0] and not header:
                header = True
                continue

            if not header:
                if line[0] == 'PixelSpacing':
                    datadict[line[0]] = float(line[2])
                elif line[0] == 'Voltage':
                    datadict[line[0]] = int(line[2])
                elif line[0] == 'ImageSize':
                    try:
                        datadict[line[0]] = min(int(line[2]), int(line[3]))
                    except:
                        pass
                elif 'axis' in line:
                    datadict['InPlaneRotation'] = float(
                        line[6].strip(',')) - 250
                continue

            if line[0] in datadict.keys():
                if line[0] == 'RotationAngle': line[0] = 'RotationTheta'
                try:
                    datadict[line[0]] = float(line[2])
                except:
                    fname = os.path.basename(line[2].replace('\\', '/'))
                    datadict['FileName'] = fname
                    if fname in annotated.keys():
                        annotated[fname] += 1

            if '[ZValue' == line[0] or nn + 1 == len(mdocdata):
                data = [
                    0.,
                ] * len(datatype)
                for n, (description, dtype) in enumerate(datatype):
                    if description in datadict.keys():
                        data[n] = datadict[description]
                if 'Defocus' in datadict.keys():
                    data[0] = datadict['Defocus']
                    data[1] = datadict['Defocus']

                if 'AcquisitionOrder' == datatype[-2][0]:
                    data[-2] = nrTiltImages
                    nrTiltImages += 1

                metadata.append(tuple(data))

        if len(metadata) == 0: continue
        a = numpy.rec.array(metadata, dtype=datatype)
        a = numpy.sort(a, order='TiltAngle')

        outname = mdocfilepath.replace('mdoc', 'meta')
        if target:
            outname = os.path.join(target, mdocfile.replace('mdoc', 'meta'))
        savestar(outname, a, fmt=fmt, header=headerText)

    if mdoc_only: return

    acquisition_order = {}
    size = {}

    for k, v in annotated.items():
        if v == 0:
            tomoname = k.split('_')[0]
            if not tomoname in tomo_from_filename.keys():
                tomo_from_filename[tomoname] = []

                if k.split('.')[-1] in ('mrc', 'em'):
                    vol = read(os.path.join(nanographfolder, k))
                    data = copy.deepcopy(vol2npy(vol))
                    size[tomoname] = numpy.min(data.shape)
                else:

                    #try:
                    #    data = imread( os.path.join(nanographfolder,k) )
                    #    size[tomoname] = numpy.min(data.shape)
                    #except:
                    aa = os.popen(
                        'header {} | grep "Number of columns, rows, sections" '
                        .format(os.path.join(nanographfolder, k))).read()[:-1]
                    dd = list(map(int, aa.split()[-3:-1]))
                    size[tomoname] = numpy.min(dd)

            #Find tiltangle

            if k.endswith('em'):
                fileHeader = read_em_header(os.path.join(nanographfolder, k))
                tiltangle = fileHeader.get_tiltangle()

            elif k.endswith('mrc'):
                tiltangle = read_angle(os.path.join(nanographfolder, k))
            else:
                tiltangle = 0.

            tomo_from_filename[tomoname].append([
                k.replace('[', '_').replace(']', '_').split('_'), tiltangle, k
            ])

        if v == 'st':
            from pytom.tompy.io import read as readNPY, read_size, read_pixelsize
            from numpy import loadtxt

            stackfile = os.path.join(nanographfolder, k)
            tltfile = stackfile.replace('.st', '.tlt')

            x, y, z = read_size(os.path.join(nanographfolder, k))
            pixelsize = read_pixelsize(stackfile, 'x')

            print(f'\n\n\n{tltfile}')

            if not os.path.exists(tltfile):
                print(f'failed for {tltfile}')
                continue

            tiltangles = loadtxt(tltfile)

            tomoname = k[:-3]

            metadata = numpy.zeros((len(tiltangles)), dtype=datatype)

            for i, tiltangle in enumerate(tiltangles):

                metadata['TiltAngle'][i] = tiltangle
                metadata['FileName'][
                    i] = f'{nanographfolder}/IMODSTACK_{tomoname}_{i:02d}.mrc'
                metadata['ImageSize'][i] = min(x, y)
                metadata['PixelSpacing'][i] = pixelsize
                metadata['DefocusU'][i] = 3
                metadata['DefocusV'][i] = 3
                metadata['Voltage'][i] = 200
                metadata['SphericalAberration'][i] = 2.7
                metadata['AmplitudeContrast'][i] = 0.8
                metadata['MarkerDiameter'][i] = 100

            a = numpy.sort(metadata, order='TiltAngle')

            outname = '{}/{}.meta'.format(nanographfolder, tomoname)
            print(outname)
            savestar(outname, a, fmt=fmt, header=headerText)

    for NR, (k, v) in enumerate(tomo_from_filename.items()):

        neg = numpy.array([
            0,
        ] * len(v[0][0]), dtype=int)
        tiltangles_header = []
        for list2, angle, fname in v:
            tiltangles_header.append(angle)
            for n, part in enumerate(list2):
                if '-' in part:
                    neg[n] += 1

        loc = numpy.argmax(neg[neg < len(v)])

        if not neg[loc] > 0:
            loc = -1

        tiltangles_header = numpy.array(tiltangles_header)
        metadata = [
            [
                0.,
            ] * len(datatype),
        ] * len(v)

        for NR, (d, t) in enumerate(datatype):
            if d == 'TiltAngle':

                break

        if len(v) < 10:
            return

        if loc > -0.5:
            for i in range(len(v)):
                metadata[i][NR] = float(v[i][0][loc])
                metadata[i][-1] = v[i][2]
                if datatype[-3][0] == 'ImageSize': metadata[i][-3] = size[k]
                metadata[i] = tuple(metadata[i])

        elif len(numpy.unique(numpy.round(tiltangles_header).astype(
                int))) == len(tiltangles_header):
            for i in range(len(v)):
                metadata[i][NR] = float(tiltangles_header[i])
                metadata[i][-1] = v[i][2]
                if datatype[-3][0] == 'ImageSize': metadata[i][-3] = size[k]
                metadata[i] = tuple(metadata[i])

        else:
            continue

        a = numpy.rec.array(metadata, dtype=datatype)
        a = numpy.sort(a, order='TiltAngle')

        outname = '{}/{}.meta'.format(nanographfolder, v[0][0][0])
        savestar(outname, a, fmt=fmt, header=headerText)
Пример #6
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]
Пример #7
0
def averageGPU(particleList,
               averageName,
               showProgressBar=False,
               verbose=False,
               createInfoVolumes=False,
               weighting=False,
               norm=False,
               gpuId=None,
               profile=True):
    """
    average : Creates new average from a particleList
    @param particleList: The particles
    @param averageName: Filename of new average
    @param verbose: Prints particle information. Disabled by default.
    @param createInfoVolumes: Create info data (wedge sum, inverted density) too? False by default.
    @param weighting: apply weighting to each average according to its correlation score
    @param norm: apply normalization for each particle
    @return: A new Reference object
    @rtype: L{pytom.basic.structures.Reference}
    @author: Thomas Hrabe
    @change: limit for wedgeSum set to 1% or particles to avoid division by small numbers - FF
    """
    import time
    from pytom.tompy.io import read, write, read_size
    from pytom.tompy.filter import bandpass as lowpassFilter, rotateWeighting, applyFourierFilter, applyFourierFilterFull, create_wedge
    from pytom.voltools import transform, StaticVolume
    from pytom.basic.structures import Reference
    from pytom.tompy.normalise import mean0std1
    from pytom.tompy.tools import volumesSameSize, invert_WedgeSum, create_sphere
    from pytom.tompy.transform import fourier_full2reduced, fourier_reduced2full
    from cupyx.scipy.fftpack.fft import fftn as fftnP
    from cupyx.scipy.fftpack.fft import ifftn as ifftnP
    from cupyx.scipy.fftpack.fft import get_fft_plan
    from pytom.tools.ProgressBar import FixedProgBar
    from multiprocessing import RawArray
    import numpy as np
    import cupy as xp

    if not gpuId is None:
        device = f'gpu:{gpuId}'
        xp.cuda.Device(gpuId).use()
    else:
        print(gpuId)
        raise Exception('Running gpu code on non-gpu device')
    print(device)
    cstream = xp.cuda.Stream()
    if profile:
        stream = xp.cuda.Stream.null
        t_start = stream.record()

    # from pytom.tools.ProgressBar import FixedProgBar
    from math import exp
    import os

    if len(particleList) == 0:
        raise RuntimeError('The particle list is empty. Aborting!')

    if showProgressBar:
        progressBar = FixedProgBar(0, len(particleList), 'Particles averaged ')
        progressBar.update(0)
        numberAlignedParticles = 0

    # pre-check that scores != 0
    if weighting:
        wsum = 0.
        for particleObject in particleList:
            wsum += particleObject.getScore().getValue()
        if wsum < 0.00001:
            weighting = False
            print("Warning: all scores have been zero - weighting not applied")
    import time
    sx, sy, sz = read_size(particleList[0].getFilename())
    wedgeInfo = particleList[0].getWedge().convert2numpy()
    print('angle: ', wedgeInfo.getWedgeAngle())
    wedgeZero = xp.fft.fftshift(
        xp.array(wedgeInfo.returnWedgeVolume(sx, sy, sz, True).get(),
                 dtype=xp.float32))
    # wedgeZeroReduced = fourier_full2reduced(wedgeZero)
    wedge = xp.zeros_like(wedgeZero, dtype=xp.float32)
    wedgeSum = xp.zeros_like(wedge, dtype=xp.float32)
    print('init texture')
    wedgeText = StaticVolume(xp.fft.fftshift(wedgeZero),
                             device=device,
                             interpolation='filt_bspline')

    newParticle = xp.zeros((sx, sy, sz), dtype=xp.float32)

    centerX = sx // 2
    centerY = sy // 2
    centerZ = sz // 2

    result = xp.zeros((sx, sy, sz), dtype=xp.float32)

    fftplan = get_fft_plan(wedge.astype(xp.complex64))

    n = 0

    total = len(particleList)
    # total = int(np.floor((11*1024**3 - mempool.total_bytes())/(sx*sy*sz*4)))
    # total = 128
    #
    #
    # particlesNP = np.zeros((total, sx, sy, sz),dtype=np.float32)
    # particles = []
    # mask = create_sphere([sx,sy,sz], sx//2-6, 2)
    # raw = RawArray('f', int(particlesNP.size))
    # shared_array = np.ctypeslib.as_array(raw)
    # shared_array[:] = particlesNP.flatten()
    # procs = allocateProcess(particleList, shared_array, n, total, wedgeZero.size)
    # del particlesNP

    if profile:
        t_end = stream.record()
        t_end.synchronize()

        time_took = xp.cuda.get_elapsed_time(t_start, t_end)
        print(f'startup time {n:5d}: \t{time_took:.3f}ms')
        t_start = stream.record()

    for particleObject in particleList:

        rotation = particleObject.getRotation()
        rotinvert = rotation.invert()
        shiftV = particleObject.getShift()

        # if n % total == 0:
        #     while len(procs):
        #         procs =[proc for proc in procs if proc.is_alive()]
        #         time.sleep(0.1)
        #         print(0.1)
        #     # del particles
        #     # xp._default_memory_pool.free_all_blocks()
        #     # pinned_mempool.free_all_blocks()
        #     particles = xp.array(shared_array.reshape(total, sx, sy, sz), dtype=xp.float32)
        #     procs = allocateProcess(particleList, shared_array, n, total, size=wedgeZero.size)
        #     #pinned_mempool.free_all_blocks()
        #     #print(mempool.total_bytes()/1024**3)

        particle = read(particleObject.getFilename(), deviceID=device)

        #particle = particles[n%total]

        if norm:  # normalize the particle
            mean0std1(particle)  # happen inplace

        # apply its wedge to
        #particle = applyFourierFilter(particle, wedgeZeroReduced)
        #particle = (xp.fft.ifftn( xp.fft.fftn(particle) * wedgeZero)).real
        particle = (ifftnP(fftnP(particle, plan=fftplan) * wedgeZero,
                           plan=fftplan)).real

        ### create spectral wedge weighting

        wedge *= 0

        wedgeText.transform(
            rotation=[rotinvert[0], rotinvert[2], rotinvert[1]],
            rotation_order='rzxz',
            output=wedge)
        #wedge = xp.fft.fftshift(fourier_reduced2full(create_wedge(30, 30, 21, 42, 42, 42, rotation=[rotinvert[0],rotinvert[2], rotinvert[1]])))
        # if analytWedge:
        #     # > analytical buggy version
        # wedge = wedgeInfo.returnWedgeVolume(sx, sy, sz, True, rotinvert)
        # else:
        #     # > FF: interpol bugfix

        # wedge = rotateWeighting(weighting=wedgeInfo.returnWedgeVolume(sx, sy, sz, True), rotation=[rotinvert[0], rotinvert[2], rotinvert[1]])
        #     # < FF
        #     # > TH bugfix
        #     # wedgeVolume = wedgeInfo.returnWedgeVolume(wedgeSizeX=sizeX, wedgeSizeY=sizeY, wedgeSizeZ=sizeZ,
        #     #                                    humanUnderstandable=True, rotation=rotinvert)
        #     # wedge = rotate(volume=wedgeVolume, rotation=rotinvert, imethod='linear')
        #     # < TH

        ### shift and rotate particle

        newParticle *= 0
        transform(particle,
                  output=newParticle,
                  rotation=[-rotation[1], -rotation[2], -rotation[0]],
                  center=[centerX, centerY, centerZ],
                  translation=[-shiftV[0], -shiftV[1], -shiftV[2]],
                  device=device,
                  interpolation='filt_bspline',
                  rotation_order='rzxz')

        #write(f'trash/GPU_{n}.em', newParticle)
        # print(rotation.toVector())
        # break
        result += newParticle
        wedgeSum += xp.fft.fftshift(wedge)
        # if showProgressBar:
        #     numberAlignedParticles = numberAlignedParticles + 1
        #     progressBar.update(numberAlignedParticles)

        if n % total == 0:
            if profile:
                t_end = stream.record()
                t_end.synchronize()

                time_took = xp.cuda.get_elapsed_time(t_start, t_end)
                print(f'total time {n:5d}: \t{time_took:.3f}ms')
                t_start = stream.record()
        cstream.synchronize()
        n += 1

    print('averaged particles')
    ###apply spectral weighting to sum

    result = lowpassFilter(result, high=sx / 2 - 1, sigma=0)
    # if createInfoVolumes:
    write(averageName[:len(averageName) - 3] + '-PreWedge.em', result)
    write(averageName[:len(averageName) - 3] + '-WedgeSumUnscaled.em',
          fourier_full2reduced(wedgeSum))

    wedgeSumINV = invert_WedgeSum(wedgeSum,
                                  r_max=sx // 2 - 2.,
                                  lowlimit=.05 * len(particleList),
                                  lowval=.05 * len(particleList))
    wedgeSumINV = wedgeSumINV

    #print(wedgeSum.mean(), wedgeSum.std())
    if createInfoVolumes:
        write(averageName[:len(averageName) - 3] + '-WedgeSumInverted.em',
              xp.fft.fftshift(wedgeSumINV))

    result = applyFourierFilterFull(result, xp.fft.fftshift(wedgeSumINV))

    # do a low pass filter
    result = lowpassFilter(result, sx / 2 - 2, (sx / 2 - 1) / 10.)[0]
    write(averageName, result)

    if createInfoVolumes:
        resultINV = result * -1
        # write sign inverted result to disk (good for chimera viewing ... )
        write(averageName[:len(averageName) - 3] + '-INV.em', resultINV)

    newReference = Reference(averageName, particleList)

    return newReference
Пример #8
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
Пример #9
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)
Пример #10
0
def polish_particles(particle_list_filename,
                     projection_directory,
                     averaged_subtomogram,
                     binning,
                     offset,
                     projections,
                     tilt_angles,
                     mpi,
                     fsc_path='',
                     peak_border=75,
                     outputDirectory='./',
                     create_graphics=False,
                     number_of_particles=0,
                     verbose=False):
    """
    To polish a particle list based on (an) initial subtomogram(s).

    :param particle_list_filename: the filename of the particlelist
    :type particle_list_filename: str
    :param projection_directory: the directory of the projections
    :type projection_directory: str
    :param averaged_subtomogram: to give a path to an averaged subtomogram to be used instead of subtomograms of all
               particles separately
    :type averaged_subtomogram: str
    :param binning: the binning factor used
    :type binning: int
    :param offset: the offset used (x, y, z)
    :type offset: list(int, int, int)

    :param projections: a list with filenames of projections
    :type projections: list(str)
    :param tilt_angles: the list of tiltangles used
    :type tilt_angles: list(int)
    :param mpi: the instance of mpi which can be used for multi threading
    :type mpi: mpi instance
    :param create_graphics: to create plots of major parts of the algorithm, mainly used for debugging
               and initial creation
    :type create_graphics: bool
    :param number_of_particles: to use a subset of the particles for the particle polishing
    :type number_of_particles: int
    :param skip_alignment: skips the alignment phase, does not do particle polishing
    :type skip_alignment: bool

    :return: nothing, it writes everything to disk
    :returntype: void
    """
    assert number_of_particles == -1 or number_of_particles > 0
    assert binning > 0
    assert vol_size > 0
    assert vol_size % 2 == 0
    assert isinstance(projections, list)
    assert isinstance(vol_size, int)
    assert isinstance(binning, int)
    assert isinstance(offset, list) and len(offset) == 3
    assert isinstance(offset[0], int) and isinstance(
        offset[1], int) and isinstance(offset[2], int)
    assert isinstance(tilt_angles, list)
    assert isinstance(particle_list_filename, str)
    assert isinstance(projection_directory, str)
    assert isinstance(create_graphics, bool)
    assert isinstance(averaged_subtomogram, str)
    assert isinstance(number_of_particles, int)
    assert isinstance(skip_alignment, bool)

    import numpy as np
    import os
    from pytom.tompy.io import read_size, read
    from pytom.basic.datatypes import fmtLAR, headerLocalAlignmentResults, LOCAL_ALIGNMENT_RESULTS

    # load particle list
    from pytom.basic.structures import ParticleList

    particlelist = ParticleList()
    particlelist.fromXMLFile(particle_list_filename)
    particle_list_name = os.path.splitext(
        os.path.basename(str(particle_list_filename)))[0]
    if number_of_particles > 0:
        particlelist = particlelist[:number_of_particles]

    if verbose:
        print(len(particlelist))
        print("{:s}> Creating the input array".format(gettime()))

    dimz = read_size(particlelist[0].getPickPosition().getOriginFilename(),
                     'z') * binning
    vol_size = read_size(particlelist[0].getFilename(), 'x')
    input_to_processes = []

    # data = {}
    # for projectioname in projections:
    #     data[projectioname] = read(projectioname)
    #
    # template = read(averaged_subtomogram)
    input_to_processes = []
    for particle_number, particle in enumerate(particlelist):

        rot = (particle.getRotation().getZ1(), particle.getRotation().getX(),
               particle.getRotation().getZ2())

        # loop over tiltrange, take patch and cross correlate with reprojected subtomogram
        for img, ang in zip(projections, tilt_angles):
            input_to_processes.append([
                averaged_subtomogram,
                ang,
                offset,
                vol_size,
                particle.getPickPosition().toVector(),
                rot,
                particle.getFilename(),
                particle_number,
                binning,
                img,
                create_graphics,
                fsc_path,
                dimz,
                peak_border,
            ])

    if verbose:
        print(len(input_to_processes))
        print("{:s}> Created the input array".format(gettime()))

    if verbose: print("{:s}> Started on running the process".format(gettime()))

    lists = list(zip(*input_to_processes))
    if verbose: print(len(list(lists)))

    output = mpi.parfor(
        run_single_tilt_angle,
        list(
            zip(lists[0], lists[1], lists[2], lists[3], lists[4], lists[5],
                lists[6], lists[7], lists[8], lists[9], lists[10], lists[11],
                lists[12], lists[13])))  # Some problem internally 23/10/2019

    results_file = os.path.join(outputDirectory,
                                f"resultsPolish_{particle_list_name}.txt")
    np.savetxt(results_file,
               np.array(output, dtype=LOCAL_ALIGNMENT_RESULTS),
               fmt=fmtLAR,
               header=headerLocalAlignmentResults)

    if verbose: print("{:s}> Ran the processes".format(gettime()))
Пример #11
0
        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()
def polish_particles(particle_list_filename,
                     projection_directory,
                     averaged_subtomogram,
                     binning,
                     offset,
                     projections,
                     tilt_angles,
                     fsc_path='',
                     peak_border=75,
                     outputDirectory='./',
                     create_graphics=False,
                     number_of_particles=0,
                     verbose=False,
                     gpuID=-1):
    """
    To polish a particle list based on (an) initial subtomogram(s).

    :param particle_list_filename: the filename of the particlelist
    :type particle_list_filename: str
    :param projection_directory: the directory of the projections
    :type projection_directory: str
    :param averaged_subtomogram: to give a path to an averaged subtomogram to be used instead of subtomograms of all
               particles separately
    :type averaged_subtomogram: str
    :param binning: the binning factor used
    :type binning: int
    :param offset: the offset used (x, y, z)
    :type offset: list(int, int, int)

    :param projections: a list with filenames of projections
    :type projections: list(str)
    :param tilt_angles: the list of tiltangles used
    :type tilt_angles: list(int)
    :param create_graphics: to create plots of major parts of the algorithm, mainly used for debugging
               and initial creation
    :type create_graphics: bool
    :param number_of_particles: to use a subset of the particles for the particle polishing
    :type number_of_particles: int
    :param skip_alignment: skips the alignment phase, does not do particle polishing
    :type skip_alignment: bool

    :return: nothing, it writes everything to disk
    :returntype: void
    """
    assert number_of_particles == -1 or number_of_particles > 0
    assert binning > 0
    assert vol_size > 0
    assert vol_size % 2 == 0
    assert isinstance(projections, list)
    assert isinstance(vol_size, int)
    assert isinstance(binning, int)
    assert isinstance(offset, list) and len(offset) == 3
    assert isinstance(offset[0], int) and isinstance(
        offset[1], int) and isinstance(offset[2], int)
    assert isinstance(tilt_angles, list)
    assert isinstance(particle_list_filename, str)
    assert isinstance(projection_directory, str)
    assert isinstance(create_graphics, bool)
    assert isinstance(averaged_subtomogram, str)
    assert isinstance(number_of_particles, int)
    assert isinstance(skip_alignment, bool)

    import os, time
    from pytom.tompy.io import read_size, read
    from pytom.gui.guiFunctions import fmtLAR, headerLocalAlignmentResults, LOCAL_ALIGNMENT_RESULTS
    import pytom.voltools as vt

    # load particle list
    from pytom.basic.structures import ParticleList

    particlelist = ParticleList()
    particlelist.fromXMLFile(particle_list_filename)
    particle_list_name = os.path.splitext(
        os.path.basename(str(particle_list_filename)))[0]
    if number_of_particles > 0:
        particlelist = particlelist[:number_of_particles]

    if verbose:
        print(len(particlelist))
        print("{:s}> Creating the input array".format(gettime()))

    dimz = read_size(particlelist[0].getPickPosition().getOriginFilename(),
                     'z') * binning
    vol_size = 200
    input_to_processes = []

    data = {}

    for projectioname in projections:
        data[projectioname] = xp.array(read(projectioname))


#
    template1 = read(averaged_subtomogram, order='F')

    #template1 = mrcfile.open(averaged_subtomogram,permissive=True).data.copy().T.copy()

    template = vt.StaticVolume(template1,
                               interpolation='filt_bspline',
                               device=device)

    # output = []
    results_file = os.path.join(outputDirectory,
                                f"resultsPolish_{particle_list_name}.txt")

    results = []

    for particle_number, particle in enumerate(particlelist):

        rot = (particle.getRotation().getZ1(), particle.getRotation().getX(),
               particle.getRotation().getZ2())
        # loop over tiltrange, take patch and cross correlate with reprojected subtomogram
        for img, ang in zip(projections, tilt_angles):
            pick_position = particle.getPickPosition().toVector()

            result = run_single_tilt_angle(template, ang, offset, vol_size,
                                           pick_position, rot,
                                           particle.getFilename(),
                                           particle_number, binning, data,
                                           create_graphics, fsc_path, dimz,
                                           peak_border, img,
                                           averaged_subtomogram)
            results.append(tuple(result))

    try:

        np.savetxt(results_file,
                   np.array(results, dtype=LOCAL_ALIGNMENT_RESULTS),
                   fmt=fmtLAR,
                   header=headerLocalAlignmentResults)
    except Exception as e:
        print(e)
        for res in results:
            print('{:7d} {:15.3f} {:15.3f} {:15.3f} {:15.3f} {:15.10f} {:s}'.
                  format(*res))
            break

    if verbose: print("{:s}> Ran the processes".format(gettime()))