def average(self, mask=None): """ average Image Stack @param mask: mask is multiplied with average if specified @type mask: L{pytom_volume.vol} @return: average @rtype: L{ptom_volume.vol} """ from pytom.basic.transformations import general_transform2d if self.averageData == None: self.averageData = vol(self.dimX, self.dimY, 1) self.averageData.setAll(0.) for ii in range(0, len(self.images)): self.imageCopies[ii].data = general_transform2d( v=self.images[ii].data, rot=-self.images[ii].rotation, shift=[-self.images[ii].shiftX, -self.images[ii].shiftY], scale=1., order=[2, 1, 0], crop=True) self.averageData = self.averageData + self.imageCopies[ii].data if mask: self.averageData = self.averageData * mask return self.averageData
def test_Origin(self): """ test that central voxel remains invariant upon magification """ newvol = general_transform2d(self.origin, rot=0., shift=None, scale=self.m) val = newvol.getV(128, 128, 0) self.assertTrue(val > 0.01, 'origin changes upon magnification change!')
def test_Transform(self): """ """ # first magnify by m, then rotate by alpha alpha = 25. self.r_trans = rotate_vector(self.r, alpha) self.r_trans = self.r_trans * self.m r_trans_round = array([0., 0.]) tline = "Approximate position after rotation and magnification: " for ii in range(0, 2): r_trans_round[ii] = int(round(self.r_trans[ii]) + 128) tline = tline + ("%6d " % r_trans_round[ii]) print(tline) newvol = general_transform2d(self.myVol, rot=alpha, shift=None, scale=self.m) val = newvol.getV(int(r_trans_round[0]), int(r_trans_round[1]), 0) print("value at approximate interpolated position: %5.3f" % val) tline = ( "next neighbors: %5.3f, " % newvol.getV(int(r_trans_round[0]) - 1, int(r_trans_round[1]), 0)) tline = tline + ("%5.3f, " % newvol.getV( int(r_trans_round[0]) - 1, int(r_trans_round[1]), 0)) tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0]), int(r_trans_round[1]) - 1, 0)) tline = tline + ("%5.3f, " % newvol.getV( int(r_trans_round[0]) + 1, int(r_trans_round[1]), 0)) tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0]), int(r_trans_round[1]) + 1, 0)) tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] + 1), int(r_trans_round[1]) + 1, 0)) tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] + 1), int(r_trans_round[1]) - 1, 0)) tline = tline + ("%5.3f, " % newvol.getV(int(r_trans_round[0] - 1), int(r_trans_round[1]) + 1, 0)) tline = tline + ("%5.3f\n" % newvol.getV(int(r_trans_round[0] - 1), int(r_trans_round[1]) - 1, 0)) print(tline) self.assertTrue(val > 0.01, 'wrong point !=0!')
def writeAlignedProjections(TiltSeries_, weighting=None, lowpassFilter=None, binning=None, verbose=False, write_images=True): """write weighted and aligned projections to disk1 @param TiltSeries_: Tilt Series @type TiltSeries_: reconstruction.TiltSeries @param weighting: weighting (<0: analytical weighting, >1 exact weighting (value corresponds to object diameter in pixel AFTER binning) @type weighting: float @param lowpassFilter: lowpass filter (in Nyquist) @type lowpassFilter: float @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc. @author: FF """ import numpy from pytom_numpy import vol2npy from pytom.basic.files import read_em, write_em from pytom.basic.functions import taper_edges from pytom.basic.transformations import general_transform2d from pytom.basic.fourier import ifft, fft from pytom.basic.filter import filter as filterFunction, bandpassFilter from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, rotateFilter from pytom_volume import complexRealMult, vol import pytom_freqweight from pytom.basic.transformations import resize from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatypeAR import os if binning: imdim = int(float(TiltSeries_._imdim) / float(binning) + .5) else: imdim = TiltSeries_._imdim print('imdim', imdim) sliceWidth = imdim # pre-determine analytical weighting function and lowpass for speedup if (weighting != None) and (weighting < -0.001): w_func = fourierFilterShift(rampFilter(imdim, imdim)) print('start weighting') # design lowpass filter if lowpassFilter: if lowpassFilter > 1.: lowpassFilter = 1. print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)") # weighting filter: arguments: (angle, cutoff radius, dimx, dimy, lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim / 2, imdim, imdim // 2 + 1, 1, lowpassFilter / 5. * imdim) #lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2), # bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1] tilt_angles = [] for projection in TiltSeries_._ProjectionList: tilt_angles.append(projection._tiltAngle) tilt_angles = sorted(tilt_angles) print(tilt_angles) #q = numpy.matrix(abs(numpy.arange(-imdim//2, imdim//2))) alignmentResults = numpy.zeros((len(TiltSeries_._ProjectionList)), dtype=datatypeAR) alignmentResults['TiltAngle'] = tilt_angles for (ii, projection) in enumerate(TiltSeries_._ProjectionList): alignmentResults['FileName'][ii] = os.path.join( os.getcwd(), projection._filename) transX = -projection._alignmentTransX / binning transY = -projection._alignmentTransY / binning rot = -(projection._alignmentRotation + 90.) mag = projection._alignmentMagnification alignmentResults['AlignmentTransX'][ii] = transX alignmentResults['AlignmentTransY'][ii] = transY alignmentResults['InPlaneRotation'][ii] = rot alignmentResults['Magnification'][ii] = mag if write_images: if projection._filename.split('.')[-1] == 'st': from pytom.basic.files import EMHeader, read header = EMHeader() header.set_dim(x=imdim, y=imdim, z=1) idx = projection._index if verbose: print("reading in projection %d" % idx) image = read(file=projection._filename, subregion=[ 0, 0, idx - 1, TiltSeries_._imdim, TiltSeries_._imdim, 1 ], sampling=[0, 0, 0], binning=[0, 0, 0]) if not (binning == 1) or (binning == None): image = resize(volume=image, factor=1 / float(binning))[0] else: # read projection files from pytom.basic.files import EMHeader, read, read_em_header print(projection._filename) image = read(projection._filename) image = resize(volume=image, factor=1 / float(binning))[0] if projection._filename[-3:] == '.em': header = read_em_header(projection._filename) else: header = EMHeader() header.set_dim(x=imdim, y=imdim, z=1) if lowpassFilter: filtered = filterFunction(volume=image, filterObject=lpf, fourierOnly=False) image = filtered[0] tiltAngle = projection._tiltAngle header.set_tiltangle(tiltAngle) # normalize to contrast - subtract mean and norm to mean immean = vol2npy(image).mean() image = (image - immean) / immean # smoothen borders to prevent high contrast oscillations image = taper_edges(image, imdim // 30)[0] # transform projection according to tilt alignment if projection._filename.split('.')[-1] == 'st': newFilename = (TiltSeries_._alignedTiltSeriesName + "_" + str(projection.getIndex()) + '.em') else: TiltSeries_._tiltSeriesFormat = 'mrc' newFilename = (TiltSeries_._alignedTiltSeriesName + "_" + str(projection.getIndex()) + '.' + TiltSeries_._tiltSeriesFormat) if verbose: tline = ("%30s" % newFilename) tline = tline + (" (tiltAngle=%6.2f)" % tiltAngle) tline = tline + (": transX=%6.1f" % transX) tline = tline + (", transY=%6.1f" % transY) tline = tline + (", rot=%6.2f" % rot) tline = tline + (", mag=%5.4f" % mag) print(tline) image = general_transform2d(v=image, rot=rot, shift=[transX, transY], scale=mag, order=[2, 1, 0], crop=True) # smoothen once more to avoid edges image = taper_edges(image, imdim // 30)[0] # analytical weighting if (weighting != None) and (weighting < 0): image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ())) elif (weighting != None) and (weighting > 0): if abs(weighting - 2) < 0.001: w_func = fourierFilterShift( rotateFilter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth)) else: w_func = fourierFilterShift( exactFilter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth)) image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ())) header.set_tiltangle(tilt_angles[ii]) if newFilename.endswith('.mrc'): data = copy.deepcopy(vol2npy(image)) mrcfile.new(newFilename, data.T.astype(float32), overwrite=True) else: write_em(filename=newFilename, data=image, header=header) if verbose: tline = ("%30s written ..." % newFilename) outname = os.path.join(os.path.dirname(TiltSeries_._alignedTiltSeriesName), 'alignmentResults.txt') numpy.savetxt(outname, alignmentResults, fmt=fmtAR, header=headerAlignmentResults) print('Alignment successful. See {} for results.'.format(outname))
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 setUp(self): from pytom.basic.functions import initSphere from pytom.image2D.imageStructures import ImageStack, Image from pytom.basic.transformations import general_transform2d import pytom.simulation.whiteNoise import random random.seed(0) self.dim = 32 self.nim = 41 self.snr = .1 self.radius = 7. self.sph = initSphere(sizeX=self.dim, sizeY=self.dim, sizeZ=1, radius=self.radius, smooth=1., maxradius=0, cent=None, filename='') self.imageStack = ImageStack() # random shift self.shiftX = [] self.shiftY = [] sumX = 0. sumY = 0. for ii in range(0, self.nim): self.shiftX.append(random.gauss(mu=0., sigma=2.)) self.shiftY.append(random.gauss(mu=0., sigma=2.)) sumX = sumX / self.nim sumY = sumY / self.nim for ii in range(0, self.nim): self.shiftX[ii] = self.shiftX[ii] - sumX self.shiftY[ii] = self.shiftY[ii] - sumY # apply shifts for ii in range(0, self.nim): image = Image(filename=None, boxCoords=[0, 0, 0], dims=[self.dim, self.dim, 1], shiftX=0, shiftY=0, appliedShiftX=0, appliedShiftY=0, rotation=0, index=ii, verbose=False) tmp = general_transform2d(v=self.sph, rot=0., shift=[self.shiftX[ii], self.shiftY[ii]], scale=1., order=[2, 1, 0], crop=True) image.data = pytom.simulation.whiteNoise.add(volume=tmp, SNR=self.snr) self.imageStack.append(image=image) self.imageStack.normalize(normtype="StdMean") self.imageStack.bandpass(lowfreq=1., hifreq=6., smooth=2., bpf=None) # smoothen edges self.imageStack.taper_edges(width=self.dim / 8.) self.imageStack.exMaxAlign(niter=10, mask=None) self.imageStack.write('input.em') self.imageStack.writeWorkingCopies('output.em')