def getTransformedVolume(self): from pytom.tompy.io import read from pytom.tompy.transform import translate3d, rotate3d v = read(self.filename) v2 = translate3d(v, -self.shift_x, -self.shift_y, -self.shift_z) v3 = rotate3d(v2, -self.rotation_psi, -self.rotation_phi, -self.rotation_the) return v3
def test(index=0): from pytom.tompy.io import read from pytom.tompy.transform import rotate3d path_raw_projection = "/data2/dschulte/BachelorThesis/Data/VPP2/03_Tomographic_Reconstruction/tomogram_000/sorted/sorted_29.em" path_aligned_projection = "/data2/dschulte/BachelorThesis/Data/VPP2/03_Tomographic_Reconstruction/tomogram_000/alignment/marker_0001_-60.0,60.0/sorted_aligned_30.em" path_template = "/data2/dschulte/BachelorThesis/Data/VPP2/05_Subtomogram_Analysis/combo_reduced.em" tilt_angle = -1.9989999533 raw_projection = read(path_raw_projection) aligned_projection = read(path_aligned_projection) template = read(path_template) dim = aligned_projection.shape[0] from pytom.basic.structures import ParticleList particlelist1 = ParticleList() particlelist1.fromXMLFile( "/data2/dschulte/BachelorThesis/Data/VPP2/04_Particle_Picking/Picked_Particles/combined_reduced_extracted/particleList_combined_reduced_tomogram_010_WBP.xml" ) align_results = (-15.3044300079, 3.7495634556, -184.3835906982, 1.0000053644) # -2 #align_results = (-1.2395387888, 4.9647006989, -184.3754882812, 1.0000000000) # 0 #pick_position = (278.12318382089245 * 8, 222.6395540890773 * 8, 268.97256780848085 * 8) #0 #pick_position = (381.21906883806 * 8, 153.61353397521387 * 8, 246.8315433927568 * 8) #74 #particle_rotation = (26.442828473505173, 44.44149544840194, 58.160958298848676) #0 #particle_rotation = (85.2456894956599, 30.815061362336394, 9.543300915975514) #74 pick_position = particlelist1[index].getPickPosition().toVector() particle_rotation = (particlelist1[index].getRotation().getZ1(), particlelist1[index].getRotation().getX(), particlelist1[index].getRotation().getZ2()) print(pick_position, particle_rotation) align_transformation, raw_position, aligned_position, template_transformation = combine_trans_projection( align_results, pick_position, particle_rotation, tilt_angle, dim, 8, template.shape[0]) d = 100 raw_patch = raw_projection[int(raw_position[0] - d):int(raw_position[0] + d), int(raw_position[1] - d):int(raw_position[1] + d)].squeeze() raw_patch = raw_patch / np.mean(raw_patch) aligned_patch = aligned_projection[int(aligned_position[0] - d):int(aligned_position[0] + d), int(aligned_position[1] - d):int(aligned_position[1] + d)].squeeze() aligned_patch = aligned_patch / (np.mean(aligned_patch)) aligned_raw = matrix_apply_to_2d(aligned_projection.squeeze(), align_transformation) aligned_raw_patch = aligned_raw[int(raw_position[0] - d):int(raw_position[0] + d), int(raw_position[1] - d):int(raw_position[1] + d)].squeeze() aligned_raw_patch = aligned_raw_patch / (np.mean(aligned_raw_patch)) transformed_template = matrix_apply_to_3d_3x3(template, template_transformation) print(np.mean(transformed_template), np.mean(template)) template_2d = transformed_template.sum(axis=2) template_2d = template_2d / np.mean(template_2d) print(template_2d.shape) template_vol = rotate3d(template, phi=particle_rotation[0], the=particle_rotation[1], psi=particle_rotation[2]) template_vol = rotate3d(template_vol, the=tilt_angle) template_vol_2d = template_vol.sum(axis=2) from pytom.reconstruction.reconstruct_local_alignment import normalised_cross_correlation_numpy, find_sub_pixel_max_value_2d raw_cc = normalised_cross_correlation_numpy(raw_patch, template_2d) rx, ry, _ = find_sub_pixel_max_value_2d(raw_cc) aligned_cc = normalised_cross_correlation_numpy(aligned_patch, template_vol_2d) tx, ty, _ = find_sub_pixel_max_value_2d(aligned_cc) import pylab as pl import scipy f, ax = pl.subplots(2, 3, figsize=(15, 10)) for i in range(2): for j in range(3): ax[i][j].axis('off') ax[0][0].set_title('Raw Data Particle') ax[0][0].imshow(scipy.ndimage.gaussian_filter(raw_patch, 3)) ax[0][1].set_title('Template Transformed to Raw Data') ax[0][1].imshow(template_2d) ax[0][2].set_title('Cross Correlation') ax[0][2].imshow(raw_cc) ax[0][2].text(0.05, 0.05, 'Peak\nx: {0:.2f}\ny: {0:.2f}'.format(rx, ry), transform=ax[0][2].transAxes, color='white') ax[1][0].set_title('Aligned Data Particle') ax[1][0].imshow(scipy.ndimage.gaussian_filter(aligned_patch, 3)) ax[1][1].set_title('Template Aligned to Aligned Data') ax[1][1].imshow(template_vol_2d) ax[1][2].set_title('Cross Correlation') ax[1][2].imshow(aligned_cc) ax[1][2].text(0.05, 0.05, 'Peak\nx: {0:.2f}\ny: {0:.2f}'.format(tx, ty), transform=ax[1][2].transAxes, color='white') f.tight_layout() pl.show()
def run_single_tilt_angle(ang, subtomogram, offset, vol_size, particle_position, particle_rotation, particle_filename, particle_number, binning, img, create_graphics, fsc_path, dimz, peak_border): """ To run a single tilt angle to allow for parallel computing @param ang: the tilt angle @type ang: int @param subtomogram: the filename of the subtomogram @type subtomogram: str @param offset: the offset used (x,y,z) @type offset: list(int, int, int) @param vol_size: the size of the volume to be reconstructed (in pixels) @type vol_size: int @param particle_position: the position of the particle in vector format, as given by particle.pickPosition().toVector() @type particle_position: tuple @param particle_rotation: the rotation of the particle (Z1/phi, X/the, Z2/psi) @type particle_rotation: tuple @param particle_filename: the filename of the particle, as given by particle.getfilename() @type particle_filename: str @param particle_number: the number of the particle, to allow for unique mapping @type particle_number: int @param binning: the binning factor used @type binning: int @param img: the filename of the projection to be used @type img: str @param create_graphics: to flag if images should be created for human inspection of the work done @type create_graphics: bool @return: the newly found positions of the particle, as a list in the LOCAL_ALIGNMENT_RESULTS format @returntype: list """ print(ang, offset, binning, particle_position) from pytom.tompy.transform import rotate3d import numpy as np from math import cos, sin, pi from pytom.tompy.transform import cut_from_projection from pytom.tompy.io import read subtomogram = read(subtomogram) img = read(img) # Get the size of the original projection dim_x = img.shape[0] dim_z = dim_x if dimz is None else dimz print(dim_x, dim_z) x, y, z = particle_position x = (x + offset[0]) * binning y = (y + offset[1]) * binning z = (z + offset[2]) * binning # Get template # First rotate towards orientation of the particle, then to the tilt angle rotated1 = rotate3d(subtomogram, phi=particle_rotation[0], the=particle_rotation[1], psi=particle_rotation[2]) rotated2 = rotate3d(rotated1, the=ang) # 'the' is the rotational axis template = rotated2.sum(axis=2) # Get coordinates of the paricle adjusted for the tilt angle yy = y # assume the rotation axis is around y xx = (cos(ang * pi / 180) * (x - dim_x / 2) - sin(ang * pi / 180) * (z - dim_z / 2)) + dim_x / 2 # Cut the small patch out patch = cut_from_projection(img.sum(axis=2), [xx, yy], [vol_size, vol_size]) patch = patch - patch.mean() # Filter using FSC fsc_mask = None import os if os.path.isfile(fsc_path): f = open(fsc_path, "r") fsc = map(lambda a: float(a), f.readlines()) f.close() fsc_mask = create_fsc_mask(fsc, vol_size) elif fsc_path != "": print("Not an existing FSC file: " + fsc_path) # Cross correlate the template and patch, this should give the pixel shift it is after ccf = normalised_cross_correlation(template, patch, fsc_mask) points2d = find_sub_pixel_max_value_2d(ccf, ignore_border=peak_border) x_diff = points2d[0] - vol_size / 2 y_diff = points2d[1] - vol_size / 2 if create_graphics: # Create an image to display and/or test the inner workings of the algorithm m_style = dict(color='tab:blue', linestyle=':', marker='o', markersize=5, markerfacecoloralt='tab:red') m_style_alt = dict(color='tab:red', linestyle=':', marker='o', markersize=5, markerfacecoloralt='tab:blue') points = find_sub_pixel_max_value(ccf) nx, ny, nz = particle_position nx += x_diff ny += y_diff npatch = cut_from_projection( img.sum(axis=2), [xx + x_diff, yy + y_diff], [vol_size, vol_size] ) # img.sum(axis=2)[int(xx+x_diff-v):int(xx+x_diff+v), int(yy+y_diff-v):int(yy+y_diff+v)] # npatch = npatch - np.mean(npatch) nccf = normalised_cross_correlation(template, npatch.squeeze()) npoints = find_sub_pixel_max_value(nccf) npoints2d = find_sub_pixel_max_value_2d(nccf, ignore_border=peak_border) import pylab as pp grid = pp.GridSpec(3, 3, wspace=0, hspace=0.35, left=0.05, right=0.95, top=0.90, bottom=0.05) ax_0_0 = pp.subplot(grid[0, 0]) ax_0_1 = pp.subplot(grid[0, 1]) ax_0_2 = pp.subplot(grid[0, 2]) ax_1_0 = pp.subplot(grid[1, 0]) ax_1_1 = pp.subplot(grid[1, 1]) ax_1_2 = pp.subplot(grid[1, 2]) ax_2_0 = pp.subplot(grid[2, 0]) ax_2_1 = pp.subplot(grid[2, 1]) ax_2_2 = pp.subplot(grid[2, 2]) ax_0_0.axis('off') ax_0_1.axis('off') ax_0_2.axis('off') ax_1_0.axis('off') ax_1_1.axis('off') ax_1_2.axis('off') ax_2_0.axis('off') ax_2_1.axis('off') ax_2_2.axis('off') axis_title(ax_0_0, "Cutout") ax_0_0.imshow(patch) axis_title(ax_0_1, "Template") ax_0_1.imshow(template) axis_title(ax_0_2, "Shifted Cutout\n(based on cross correlation)") ax_0_2.imshow(npatch.squeeze()) axis_title(ax_1_0, u"Cross correlation\ncutout × template") ax_1_0.imshow(ccf) ax_1_0.plot([p[1] for p in points], [p[0] for p in points], fillstyle='none', **m_style) ax_1_0.plot([points2d[1]], [points2d[0]], fillstyle='none', **m_style_alt) ax_1_0.plot([vol_size / 2], [vol_size / 2], ",k") ax_1_1.text( 0.5, 0.8, "Red: 2D spline interpolation\nx: {:f}\ny: {:f}\nBlue: 1D spline interpolation\nx: {:f}\ny: {:f}" "\nBlack: center".format(x_diff, y_diff, points[0][0] - vol_size / 2, points[0][1] - vol_size / 2), fontsize=8, horizontalalignment='center', verticalalignment='center', transform=ax_1_1.transAxes) axis_title(ax_1_2, u"Cross correlation\nshifted cutout × template") ax_1_2.imshow(nccf) ax_1_2.plot([p[0] for p in npoints], [p[1] for p in npoints], fillstyle='none', **m_style) ax_1_2.plot([npoints2d[0]], [npoints2d[1]], fillstyle='none', **m_style_alt) ax_1_2.plot([vol_size / 2], [vol_size / 2], ",k") axis_title(ax_2_0, u"Zoom into red peak\nin CC cutout × template") d = 10 peak = ccf[int(points2d[0]) - d:int(points2d[0]) + d, int(points2d[1]) - d:int(points2d[1] + d)] ax_2_0.imshow(peak) axis_title( ax_2_1, u"Zoom into red peak\nin CC cutout × template\ninterpolated") ax_2_1.imshow(points2d[2]) axis_title(ax_2_2, u"Cutout\nGaussian filter σ3") import scipy ax_2_2.imshow(scipy.ndimage.gaussian_filter(patch, 3)) pp.savefig("polish_particle_{:04d}_tiltimage_{:05.2f}.png".format( particle_number, ang)) return particle_number, x_diff, y_diff, ang, 0, 0, particle_filename
def run_single_tilt_angle(subtomogram, ang, offset, vol_size, particle_position, particle_rotation, particle_filename, particle_number, binning, img, create_graphics, fsc_path, dimz, peak_border): """ To run a single tilt angle to allow for parallel computing @param ang: the tilt angle @type ang: int @param subtomogram: the filename of the subtomogram @type subtomogram: str @param offset: the offset used (x,y,z) @type offset: list(int, int, int) @param vol_size: the size of the volume to be reconstructed (in pixels) @type vol_size: int @param particle_position: the position of the particle in vector format, as given by particle.pickPosition().toVector() @type particle_position: tuple @param particle_rotation: the rotation of the particle (Z1/phi, X/the, Z2/psi) @type particle_rotation: tuple @param particle_filename: the filename of the particle, as given by particle.getfilename() @type particle_filename: str @param particle_number: the number of the particle, to allow for unique mapping @type particle_number: int @param binning: the binning factor used @type binning: int @param img: the filename of the projection to be used @type img: str @param create_graphics: to flag if images should be created for human inspection of the work done @type create_graphics: bool @return: the newly found positions of the particle, as a list in the LOCAL_ALIGNMENT_RESULTS format @returntype: list """ from pytom.reconstruction.reconstructionFunctions import alignImageUsingAlignmentResultFile from pytom.tompy.transform import rotate3d, rotate_axis from pytom.gui.guiFunctions import datatypeAR, loadstar import numpy as np from math import cos, sin, pi, sqrt from pytom.tompy.tools import create_circle from pytom.tompy.transform import cut_from_projection from pytom.tompy.filter import applyFourierFilterFull, bandpass_circle from pytom.tompy.io import read, write from pytom.tompy.correlation import meanUnderMask, stdUnderMask import os import time t = time.time() # print(particle_filename, ang) # Filter using FSC fsc_mask = None k = 0.01 subtomogram = read(subtomogram) * read( '/data/gijsvds/ctem/05_Subtomogram_Analysis/Alignment/GLocal/mask_200_75_5.mrc' ) import os from pytom.tompy.filter import filter_volume_by_profile, profile2FourierVol fsc_path = '' if os.path.isfile(fsc_path): profile = [line.split()[0] for line in open(fsc_path, 'r').readlines()] fsc_mask3d = profile2FourierVol(profile, subtomogram.shape) subtomogram = applyFourierFilterFull(subtomogram, fsc_mask3d) # Cross correlate the templat # e and patch, this should give the pixel shift it is after from pytom.tompy.correlation import nXcf # Get template # First rotate the template towards orientation of the particle, then to the tilt angle img = read(img) rotated1 = rotate3d(subtomogram, phi=particle_rotation[0], the=particle_rotation[1], psi=particle_rotation[2]) rotated2 = rotate_axis( rotated1, -ang, 'y') # SWITCHED TO ROTATE AXIS AND ANGLE *-1 THIS IS AN ATTEMPT template = rotated2.sum(axis=2) # write('pp1_template.mrc', template) # img = read(img) try: patch, xx, yy = cut_patch(img, ang, particle_position, dimz=dimz, vol_size=vol_size, binning=binning) mask2d = create_circle(patch.shape, radius=75, sigma=5, num_sigma=2) patch *= mask2d # write('pp1_patch.mrc', patch) if os.path.isfile(fsc_path): profile = [ line.split()[0] for line in open(fsc_path, 'r').readlines() ] fsc_mask2d = profile2FourierVol(profile, patch.shape) patch = applyFourierFilterFull(patch, fsc_mask2d) template = normalize_image(template, mask2d, mask2d.sum()) patch = normalize_image(patch, mask2d, mask2d.sum()) if 1: ff = xp.ones_like(patch) else: ff = bandpass_circle(patch.squeeze(), 6, 25, 3) ccf = normalised_cross_correlation(template, patch, ff) points2d1 = find_sub_pixel_max_value_2d(ccf.copy(), ignore_border=peak_border) points2d2 = find_sub_pixel_max_value(ccf.copy(), ignore_border=peak_border) points2d = list(points2d2[:2]) + [points2d1[-1]] x_diff = points2d[0] - vol_size / 2 y_diff = points2d[1] - vol_size / 2 dist = sqrt(x_diff**2 + y_diff**2) #rx, ry, ii, oox, ooy, x2, y2 = find_sub_pixel_max_value_voltools(ccf.copy()) #print(rx,ry, x_diff, y_diff, x2, y2, oox, ooy, ii.shape) #print(f'{particle_number:3d} {ang:5.1f}, {dist:5.2f} {x_diff} {y_diff} {ccf.max()}') if create_graphics: rx, ry, ii, oox, ooy, x2, y2 = find_sub_pixel_max_value_voltools( ccf.copy(), k=k) print(rx, ry) from scipy.ndimage.filters import gaussian_filter # Create an image to display and/or test the inner workings of the algorithm points = find_sub_pixel_max_value(ccf, ignore_border=peak_border) nx, ny, nz = particle_position nx += x_diff ny += y_diff npatch = cut_from_projection( img.squeeze(), [xx + x_diff, yy + y_diff], [vol_size, vol_size] ) # img.sum(axis=2)[int(xx+x_diff-v):int(xx+x_diff+v), int(yy+y_diff-v):int(yy+y_diff+v)] # npatch = normalize_image(npatch, mask2d, mask2d.sum()) nccf = normalised_cross_correlation(template, npatch.squeeze(), ff) npoints = find_sub_pixel_max_value(nccf, ignore_border=peak_border) npoints2d = find_sub_pixel_max_value_2d(nccf, ignore_border=peak_border) #rx, ry = abs(xp.array(npoints2d[:2]) - 100) from scipy.ndimage.filters import gaussian_filter # Create an image to display and/or test the inner workings of the algorithm points = find_sub_pixel_max_value(ccf, ignore_border=peak_border) nx, ny, nz = particle_position nx += x_diff ny += y_diff npatch = cut_from_projection( img.squeeze(), [xx + x_diff, yy + y_diff], [vol_size, vol_size] ) # img.sum(axis=2)[int(xx+x_diff-v):int(xx+x_diff+v), int(yy+y_diff-v):int(yy+y_diff+v)] # npatch = normalize_image(npatch, mask2d, mask2d.sum()) nccf = normalised_cross_correlation(template, npatch.squeeze(), ff) npoints = find_sub_pixel_max_value(nccf, ignore_border=peak_border) npoints2d = find_sub_pixel_max_value_2d(nccf, ignore_border=peak_border) #rx, ry = abs(xp.array(npoints2d[:2]) - 100) m_style = dict(color='tab:blue', linestyle=':', marker='o', markersize=5, markerfacecoloralt='tab:red') m_style_alt = dict(color='tab:red', linestyle=':', marker='o', markersize=5, markerfacecoloralt='tab:orange') grid = pp.GridSpec(3, 3, wspace=0, hspace=0.35, left=0.05, right=0.95, top=0.90, bottom=0.05) ax_0_0 = pp.subplot(grid[0, 0]) ax_0_1 = pp.subplot(grid[0, 1]) ax_0_2 = pp.subplot(grid[0, 2]) ax_1_0 = pp.subplot(grid[1, 0]) ax_1_1 = pp.subplot(grid[1, 1]) ax_1_2 = pp.subplot(grid[1, 2]) ax_2_0 = pp.subplot(grid[2, 0]) ax_2_1 = pp.subplot(grid[2, 1]) ax_2_2 = pp.subplot(grid[2, 2]) ax_0_0.axis('off') ax_0_1.axis('off') ax_0_2.axis('off') ax_1_0.axis('off') ax_1_1.axis('off') ax_1_2.axis('off') ax_2_0.axis('off') ax_2_1.axis('off') ax_2_2.axis('off') axis_title(ax_0_0, "Cutout") ax_0_0.imshow(applyFourierFilterFull(patch, xp.fft.fftshift(ff))) axis_title(ax_0_1, "Template") ax_0_1.imshow(template) axis_title(ax_0_2, "Shifted Cutout\n(based on cross correlation)") ax_0_2.imshow(npatch.squeeze()) axis_title(ax_1_0, u"Cross correlation\ncutout × template") ax_1_0.imshow(ccf) ax_1_0.plot([points[1]], [points[0]], fillstyle='none', **m_style) ax_1_0.plot([points2d[1]], [points2d[0]], fillstyle='none', **m_style_alt) ax_1_0.plot([vol_size / 2], [vol_size / 2], ",k") ax_1_1.text( 0.5, 0.8, "Red: 2D spline interpolation\nx: {:f}\ny: {:f}\nBlue: 1D spline interpolation\nx: {:f}\ny: {:f}" "\nBlack: center".format(x_diff, y_diff, points[0] - vol_size / 2, points[1] - vol_size / 2), fontsize=8, horizontalalignment='center', verticalalignment='center', transform=ax_1_1.transAxes) axis_title(ax_1_2, u"Cross correlation\nshifted cutout × template") ax_1_2.imshow(nccf) ax_1_2.plot([npoints[0]], [npoints[1]], fillstyle='none', **m_style) ax_1_2.plot([npoints2d[0]], [npoints2d[1]], fillstyle='none', **m_style_alt) ax_1_2.plot([vol_size / 2], [vol_size / 2], ",k") axis_title(ax_2_0, u"Zoom into red peak\nin CC cutout × template") d = 10 points2d = list(xp.unravel_index(ccf.argmax(), ccf.shape)) + [points2d[-1]] peak = ccf[int(points2d[0]) - d:int(points2d[0]) + d, int(points2d[1]) - d:int(points2d[1] + d)] ax_2_0.imshow(peak) axis_title( ax_2_1, u"Zoom into red peak\nin CC cutout × template\ninterpolated") ax_2_1.imshow(ii) ax_2_1.plot([y2 + (y_diff - ry) / k], [x2 + (x_diff - rx) / k], fillstyle='none', **m_style) ax_2_1.plot([y2], [x2], fillstyle='none', **m_style_alt) axis_title(ax_2_2, u"Cutout\nGaussian filter σ3") import scipy ax_2_2.imshow(scipy.ndimage.gaussian_filter(patch, 3)) pp.savefig( "../Images/test/polish_particle_{:04d}_tiltimage_{:05.2f}_shift_{:.1f}.png" .format(particle_number, ang, dist)) del img except Exception as e: print(e) x_diff = y_diff = 0 print( f'{particle_number:3d} {ang:4d} {x_diff:5.2f} {y_diff:5.2f} {points2d1[0]-patch.shape[0]//2:.2f} {points2d1[1]-patch.shape[0]//2:.2f} {time.time()-t:5.3f}' ) return particle_number, x_diff, y_diff, ang, 0, 0, particle_filename
meanT = meanUnderMask(tcp, mask, gpu=gpu) stdT = stdUnderMask(tcp, mask, meanT, gpu=gpu) if stdT > 1E-09: temp2 = (tcp - meanT) / stdT temp2 = temp * mask else: temp2 = tcp mask2 = mask if vcp.shape[0] != temp2.shape[0] or vcp.shape[1] != temp2.shape[ 1] or vcp.shape[2] != temp2.shape[2]: tempV = xp.zeros(vcp.shape) temp2 = paste_in_center(temp2, tempV, gpu=gpu) if vcp.shape[0] != mask.shape[0] or vcp.shape[1] != mask.shape[ 1] or vcp.shape[2] != mask.shape[2]: maskV = xp.zeros(vcp.shape) mask2 = paste_in_center(mask, maskV, gpu=gpu) meanV = meanVolUnderMask(vcp, temp2, gpu=gpu) stdV = stdVolUnderMask(vcp, mask2, meanV, gpu=gpu) from pytom.tompy.transform import rotate3d s = time.time() for i in range(num_angles): tcp2 = xp.array(rotate3d(temp, 10, 10, 10)) m = FLCF(vcp, temp2, mask=mask2, stdV=stdV, gpu=gpu) print((time.time() - s))