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'
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]
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."
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))
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)
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 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
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)
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()))
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()))