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()
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
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
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)
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
def update_metafile(filename, columnID, values): metadata = loadstar(filename, dtype=datatype) metadata[columnID] = values savestar(filename, metadata, fmt=fmt, header=headerText)
def parseImodShiftFile(imodShiftFile): data = loadstar(imodShiftFile) return data[:, -2:]
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)
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
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
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()
'-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,
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]
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
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)
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()