diff --git a/Insert Slice Tolerance Demo.ipynb b/Insert Slice Tolerance Demo.ipynb new file mode 100644 index 0000000..2f26ed6 --- /dev/null +++ b/Insert Slice Tolerance Demo.ipynb @@ -0,0 +1,439 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 44, + "id": "ca419b10", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "from geomstats.geometry import special_orthogonal\n", + "from scipy.spatial import QhullError\n", + "from scipy.interpolate import griddata\n", + "\n", + "\n", + "def plot_vectors(ax, vectors, color='k.'):\n", + " for vec in range(vectors.shape[1]):\n", + " ax.plot3D(vectors[0,vec], vectors[1,vec], vectors[2,vec], color)\n", + "\n", + "def plot_3d_matrix(ax, mat):\n", + " ii, jj, kk = mat.shape\n", + " for i in range(ii):\n", + " for j in range(jj):\n", + " for k in range(kk):\n", + " if mat[i,j,k].real == 1:\n", + " ax.plot3D(i, j, k, 'r.')\n", + " if mat[i,j,k].real == 0:\n", + " ax.plot3D(i, j, k, 'b.')" + ] + }, + { + "cell_type": "markdown", + "id": "4f6184f6", + "metadata": {}, + "source": [ + "We begin by defining an xy plane and a test slice. \n", + "\n", + "These are both simple in this $n=2$ case - what we have is `xy_plane` consisting of vectors to each of the four points in the x,y,z=0 grid of width and height $n=2$. \n", + "\n", + "Then, we also have `test_slice`, which assigns a value of $1$ to each of those points." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1fc7b02f", + "metadata": {}, + "outputs": [], + "source": [ + "xy_plane = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]])\n", + "test_slice = np.array([[1, 1], [1, 1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ee193a7a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes(projection='3d')\n", + "plot_vectors(ax, xy_plane.T)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "eb8c5c19", + "metadata": {}, + "source": [ + "What we want to do is to put this slice into a 3D space - in our case it is convenient to represent this 3D space as an $n\\times n\\times n$ cube of voxels. For the purposes of `griddata`, we need that cube as a set of vectors pointing to each point (the same as how we represented `xy_plane`). So, we define the $8$ vectors needed and store them in `xyz_cube`." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ba3ae521", + "metadata": {}, + "outputs": [], + "source": [ + "xyz_cube = np.array([[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "81fcd24c", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes(projection='3d')\n", + "plot_vectors(ax, xyz_cube.T)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "6e079ef8", + "metadata": {}, + "source": [ + "Now we want to use `griddata` to interpolate this slice. What is happening here is that `griddata` takes the points and values from `xy_plane` and `test_slice` and assumes they are in a 3D space that is otherwise filled with zeroes. Then, it polls each of the points in `xyz_cube` within this space, linearly interpolating their values based on what we inserted via `xy_plane` and `test_slice`. However..." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "3be269fd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "QH6154 Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point)\n", + "\n", + "While executing: | qhull d Qz Q12 Qt Qc Qbb\n", + "Options selected for Qhull 2019.1.r 2019/06/21:\n", + " run-id 1683676233 delaunay Qz-infinity-point Q12-allow-wide Qtriangulate\n", + " Qcoplanar-keep Qbbound-last _pre-merge _zero-centrum Qinterior-keep\n", + " Pgood _max-width 1 Error-roundoff 2e-15 _one-merge 1.8e-14\n", + " Visible-distance 1.2e-14 U-max-coplanar 1.2e-14 Width-outside 2.4e-14\n", + " _wide-facet 7.3e-14 _maxoutside 2.4e-14\n", + "\n", + "precision problems (corrected unless 'Q0' or an error)\n", + " 1 degenerate hyperplanes recomputed with gaussian elimination\n", + " 1 nearly singular or axis-parallel hyperplanes\n", + " 1 zero divisors during back substitute\n", + " 2 zero divisors during gaussian elimination\n", + "\n", + "The input to qhull appears to be less than 4 dimensional, or a\n", + "computation has overflowed.\n", + "\n", + "Qhull could not construct a clearly convex simplex from points:\n", + "- p3(v5): 1 1 0 0.91\n", + "- p4(v4): 0.5 0.5 0 1\n", + "- p2(v3): 0 1 0 0.45\n", + "- p1(v2): 1 0 0 0.45\n", + "- p0(v1): 0 0 0 0\n", + "\n", + "The center point is coplanar with a facet, or a vertex is coplanar\n", + "with a neighboring facet. The maximum round off error for\n", + "computing distances is 2e-15. The center point, facets and distances\n", + "to the center point are as follows:\n", + "\n", + "center point 0.5 0.5 0 0.5636\n", + "\n", + "facet p4 p2 p1 p0 distance= 0\n", + "facet p3 p2 p1 p0 distance= 0\n", + "facet p3 p4 p1 p0 distance= 0\n", + "facet p3 p4 p2 p0 distance= 0\n", + "facet p3 p4 p2 p1 distance= 0\n", + "\n", + "These points either have a maximum or minimum x-coordinate, or\n", + "they maximize the determinant for k coordinates. Trial points\n", + "are first selected from points that maximize a coordinate.\n", + "\n", + "The min and max coordinates for each dimension are:\n", + " 0: 0 1 difference= 1\n", + " 1: 0 1 difference= 1\n", + " 2: 0 0 difference= 0\n", + " 3: 0 1 difference= 1\n", + "\n", + "If the input should be full dimensional, you have several options that\n", + "may determine an initial simplex:\n", + " - use 'QJ' to joggle the input and make it full dimensional\n", + " - use 'QbB' to scale the points to the unit cube\n", + " - use 'QR0' to randomly rotate the input for different maximum points\n", + " - use 'Qs' to search all points for the initial simplex\n", + " - use 'En' to specify a maximum roundoff error less than 2e-15.\n", + " - trace execution with 'T3' to see the determinant for each point.\n", + "\n", + "If the input is lower dimensional:\n", + " - use 'QJ' to joggle the input and make it full dimensional\n", + " - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n", + " pick the coordinate with the least range. The hull will have the\n", + " correct topology.\n", + " - determine the flat containing the points, rotate the points\n", + " into a coordinate plane, and delete the other coordinates.\n", + " - add one or more points to make the input full dimensional.\n", + "\n" + ] + } + ], + "source": [ + "try:\n", + " inserted_slice = griddata(xy_plane, test_slice.reshape((4,)), xyz_cube, fill_value=0).reshape(2, 2, 2)\n", + "except QhullError as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "id": "dcbcdc63", + "metadata": {}, + "source": [ + "Rest assured there's no syntax errors here. The problemn is outlined well by the line: \n", + "\n", + "```Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point)```\n", + "\n", + "\n", + "What that means is we've inserted a 2D object and expected it to interpolate 3D data. \n", + "\n", + "Why is this a problem? Let's drop a dimension and give this some thought. We have a line of points in black and we want to interpolate the value of a red point that is near the line:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "3f48b273", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes()\n", + "x = np.linspace(0,1)\n", + "y = np.linspace(0,1)\n", + "plt.plot(x,y,'k-')\n", + "plt.plot(0.5,0.5, 'r.')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "85cfeced", + "metadata": {}, + "source": [ + "It's easy for us to say that this point is clearly on the line. And in fact, a computer would probably agree in this case. But, this isn't generally so easy because of **float precision** (or rather a lack thereof). It is entirely reasonable that this point $(0.5,0.5)$ could be represented by the computer as, e.g., $(0.499999999,0.50000001)$. **Is this on the line?**\n", + "\n", + "You might, entirely reasonably, say yes, of course it's on the line. But, unless some tolerance is introduced, the computer would say no this isn't on the line. If we did want tolerance, the actual bounds of the line might look something like:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "2936dc2d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes()\n", + "x = np.linspace(0,1)\n", + "y = np.linspace(0,1)\n", + "plt.plot(x,y,'k-')\n", + "plt.plot(x-.05,y+.05, color='black', linestyle='dotted')\n", + "plt.plot(x+.05,y-.05, color='black', linestyle='dotted')\n", + "plt.plot(0.5,0.5, 'r.')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1f516d05", + "metadata": {}, + "source": [ + "And anything within the dotted lines is \"on\" the line. \n", + "\n", + "The problem we run in to with scipy's `griddata` is that it doesn't put this tolerance here by default. When you give it an underdimensioned object, it just throws an error as it will never interpolate anything to be \"in line\" with that underdimensioned object. \n", + "\n", + "We can get around this by adding our own tolerance, in much the same way as I did with those lines above. If we add coordinates to `xy_plane` by copying the plane with some small $z$ difference, say $z \\pm 0.05$, then the plane has \"bounds\" and interpolation will know with confidence what is and isn't on the plane.\n", + "\n", + "In doing this copying, we will also need to copy `test_slice` twice. We assume that `test_slice` values are constant along $z$, as in concept this slice is still 2D. " + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "b2f1ab3f", + "metadata": {}, + "outputs": [], + "source": [ + "z_tolerance = np.array([[0, 0, 0.05],])\n", + "xy_plane_tol = np.concatenate((xy_plane + z_tolerance, xy_plane, xy_plane - z_tolerance), axis=0)\n", + "test_slice_tiled = np.tile(test_slice, (3,))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "85360c86", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes(projection='3d')\n", + "plot_vectors(ax, xy_plane_tol.T)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3fead8b8", + "metadata": {}, + "source": [ + "Do note the scale of the $z$ axis in the plot above. We have `xy_plane` with some very small tolerances in either direction of $z$. Now, when we try the interpolation again:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "4f042633", + "metadata": {}, + "outputs": [], + "source": [ + "inserted_slice = griddata(xy_plane_tol, test_slice_tiled.reshape((12,)), xyz_cube, fill_value=0).reshape(2, 2, 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "89539c4a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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VigUzIeaj4svvpjtNbdv307nLK8IcByHqqoqfP3rX8cHH3yA559/HgBw22234corr8RPf/pTjI2NwdfDmUYCALBu3TrI5XLk5+ejrq4OW7duRWZmJsbHx/Hxxx+ju7sbs7OzPo8jFjRDH4zcZrMZN954I+68886IkhvwXdGZmPAcvX3q1CmMjY3h6quvjui5lyuWZRZdSOmNj+eeew5XXXVVLC4t5uA4DmVlZXjwwQfxwAMPsJ72u+66C1arFddccw327t2L8vJyNv0jJSXFZ281tZTOzc1l6rPp6Wn09PQgPT0d+fn5on3LgYXaularRX19fcD3WiwW3Hjjjbjllltwyy23hPT7CAdutxsPPvgge2CeC1iWBBeD3/72tzhx4gTefffdpb6UqIPjOBQWFuK+++7Dvffey3raH3zwQeh0OshkMlx00UX45je/GTT89rYyplLT3t5epKamIj8/30Nq6vHeY8cgee89uHfswGhRETQaTVByW61W/Nu//Rs++9nP4vbbbw/7d+ELwSo61EfvoosuArCgxd+zZw8OHz68HML0qGBZ7sGF7qX++te/4r777sO777675P7TSwmn04n9+/fD7XbDbrdjZmbGo6ddzF6bLzXVarVITk5Gfn4+08dLjh1DwtVXA3Y7iFyOth//GBX/9m8BVXF2ux2f+9zncPnll+O+++6LWqJPSEWHj4suumjF78GX5Qre1NSEvr4+DA0NoaioCK+88soiq5zm5mb8+7//O44ePXpOkxtYCH337t2LW2+9FcCCp9rhw4fx/e9/HyMjI7jsssuwb98+QSIXjuOQkZGBjIwM5vRCRy4rlUqsfestJNjt4FwuEEKwbnoargDkdjgcuP3223HRRRdFldzAgpLw6aefxhVXXMEqOjU1NR4VnXMOhJBAf5YMb731FlmzZg2pqKgg3//+9wkhhPyf//N/yKFDhwghhFx66aUkLy+P1NfXk/r6erJ79+6gx3z77bdJdXU1qaysJI8//rjf1x04cIAAIMePH4/Mh1lCzM3NkZdffplcf/31pK6ujjzwwAPknXfeIUajkZjNZlF/ZmZmSP+LLxJnQgJxSSTEpVSSuT/9ye/rDQYDuf7668kPfvAD4na7l/pXsZwRjIch/1mWIXo0cBbXSCOG+fl5vP322zh48CDa29tZT/u2bdsEN55MTU3B+Oc/o3J8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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "ax = plt.axes(projection='3d')\n", + "plot_3d_matrix(ax, inserted_slice)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "0d6bdc4b", + "metadata": {}, + "source": [ + "Note the red coordinates represent values of $1$ and the blue values of $0$. We have an inserted slice! And no errors popped up, because scipy knew how to handle the \"2D\" slice when we told it exactly how 2D we wanted that slice to be. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "635a31d1", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/reconstructSPI/iterative_refinement/expectation_maximization.py b/reconstructSPI/iterative_refinement/expectation_maximization.py index 372f0a7..514033e 100644 --- a/reconstructSPI/iterative_refinement/expectation_maximization.py +++ b/reconstructSPI/iterative_refinement/expectation_maximization.py @@ -8,6 +8,7 @@ primal_to_fourier_3D, ) from geomstats.geometry import special_orthogonal +from scipy.interpolate import griddata from scipy.ndimage import map_coordinates from simSPI.transfer import eval_ctf @@ -50,6 +51,13 @@ def __init__(self, map_3d_init, particles, ctf_info, max_itr=7): self.particles = particles self.ctf_info = ctf_info self.max_itr = max_itr + self.insert_slice_vectorized = np.vectorize( + IterativeRefinement.insert_slice, + excluded=[ + "xyz", + ], + signature="(n,n),(3,m),(3,k)->(n,n,n),(n,n,n)", + ) def iterative_refinement(self, count_norm_const=1): """Perform iterative refinement. @@ -128,6 +136,8 @@ def iterative_refinement(self, count_norm_const=1): .reshape(map_shape) ) + xyz_voxels = IterativeRefinement.generate_cartesian_grid(n_pix, 3) + wiener_small_numbers_1 = IterativeRefinement.get_wiener_small_numbers( particles_f_1, ctfs_1 ) @@ -154,15 +164,15 @@ def iterative_refinement(self, count_norm_const=1): ) rots = IterativeRefinement.grid_SO3_uniform(n_rotations) - xy0_plane = IterativeRefinement.generate_xy_plane(n_pix) - - slices_1, xyz_rotated = IterativeRefinement.generate_slices( - half_map_3d_f_1, xy0_plane, rots + xy0_plane = IterativeRefinement.generate_cartesian_grid(n_pix, 2) + xyz_rotated_padded = IterativeRefinement.pad_and_rotate_xy_planes( + xy0_plane, rots, n_pix ) + xyz_rotated = xyz_rotated_padded[:, :, n_pix**2 : 2 * n_pix**2] - slices_2, xyz_rotated = IterativeRefinement.generate_slices( - half_map_3d_f_2, xy0_plane, rots - ) + slices_1 = IterativeRefinement.generate_slices(half_map_3d_f_1, xyz_rotated) + + slices_2 = IterativeRefinement.generate_slices(half_map_3d_f_2, xyz_rotated) map_3d_f_updated_1 = np.zeros_like(half_map_3d_f_1) map_3d_f_updated_2 = np.zeros_like(half_map_3d_f_2) @@ -215,26 +225,30 @@ def iterative_refinement(self, count_norm_const=1): ) for one_slice_idx in range(len(bayes_factors_1)): - xyz = xyz_rotated[one_slice_idx] - inserted_slice_3d_r, count_3d_r = IterativeRefinement.insert_slice( - particle_f_deconv_1.real, xyz, n_pix + xyz_planes = xyz_rotated_padded[one_slice_idx] + inserted_slice_3d_r, count_3d_r = self.insert_slice_v( + particle_f_deconv_1.real, xyz_planes, xyz_voxels + ) + inserted_slice_3d_i, count_3d_i = self.insert_slice_v( + particle_f_deconv_1.imag, xyz_planes, xyz_voxels ) - inserted_slice_3d_i, count_3d_i = IterativeRefinement.insert_slice( - particle_f_deconv_1.imag, xyz, n_pix + map_3d_f_updated_1 += np.sum( + inserted_slice_3d_r + 1j * inserted_slice_3d_i, axis=0 ) - map_3d_f_updated_1 += inserted_slice_3d_r + 1j * inserted_slice_3d_i - counts_3d_updated_1 += count_3d_r + count_3d_i + counts_3d_updated_1 += np.sum(count_3d_r + count_3d_i, axis=0) for one_slice_idx in range(len(bayes_factors_2)): - xyz = xyz_rotated[one_slice_idx] - inserted_slice_3d_r, count_3d_r = IterativeRefinement.insert_slice( - particle_f_deconv_2.real, xyz, n_pix + xyz_planes = xyz_rotated_padded[one_slice_idx] + inserted_slice_3d_r, count_3d_r = self.insert_slice_v( + particle_f_deconv_2.real, xyz_planes, xyz_voxels ) - inserted_slice_3d_i, count_3d_i = IterativeRefinement.insert_slice( - particle_f_deconv_2.imag, xyz, n_pix + inserted_slice_3d_i, count_3d_i = self.insert_slice_v( + particle_f_deconv_2.imag, xyz_planes, xyz_voxels ) - map_3d_f_updated_2 += inserted_slice_3d_r + 1j * inserted_slice_3d_i - counts_3d_updated_2 += count_3d_r + count_3d_i + map_3d_f_updated_2 += np.sum( + inserted_slice_3d_r + 1j * inserted_slice_3d_i, axis=0 + ) + counts_3d_updated_2 += np.sum(count_3d_r + count_3d_i, axis=0) map_3d_f_norm_1 = IterativeRefinement.normalize_map( map_3d_f_updated_1, counts_3d_updated_1, count_norm_const @@ -383,47 +397,58 @@ def grid_SO3_uniform(n_rotations): """ geom = special_orthogonal.SpecialOrthogonal(3, "matrix") rots = geom.random_uniform(n_rotations) + if n_rotations == 1: + rots = np.array((rots,)) negatives = np.tile(np.random.randint(2, size=n_rotations) * 2 - 1, (3, 3, 1)).T rots[:] *= negatives return rots @staticmethod - def generate_xy_plane(n_pix): - """Generate (x,y,0) plane. + def generate_cartesian_grid(n_pix, d): + """Generate (x,y,0) plane or (x,y,z) cube. - x, y axis values range [-n // 2, ..., n // 2 - 1] + Axis values range [-n // 2, ..., n // 2 - 1] Parameters ---------- n_pix : int Number of pixels along one edge of the plane. + d : int + Dimension of output. 2 or 3. Returns ------- - xy_plane : arr - Array describing xy plane in space. - Shape (3, n_pix**2) + xyz : arr + Array describing xy plane or xyz cube in space. + Shape (3, n_pix**d) """ axis_pts = np.arange(-n_pix // 2, n_pix // 2) - grid = np.meshgrid(axis_pts, axis_pts) + if d == 2: + grid = np.meshgrid(axis_pts, axis_pts) - xy_plane = np.zeros((3, n_pix**2)) + xy_plane = np.zeros((3, n_pix**2)) - for d in range(2): - xy_plane[d, :] = grid[d].flatten() + for di in range(2): + xy_plane[di, :] = grid[di].flatten() - return xy_plane + return xy_plane + if d == 3: + grid = np.meshgrid(axis_pts, axis_pts, axis_pts) - @staticmethod - def generate_slices(map_3d_f, xy_plane, rots): - """Generate slice coordinates by rotating xy plane. + xyz = np.zeros((3, n_pix**3)) - Interpolate values from map_3d_f onto 3D coordinates. + for di in range(3): + xyz[di] = grid[di].flatten() + xyz[[0, 1]] = xyz[[1, 0]] + + return xyz + raise ValueError(f"Dimension {d} received was not 2 or 3.") + @staticmethod + def generate_slices(map_3d_f, xyz_rotated): + """Generate slice coordinates via rotated xy plane. - Shift the space into a centered position before rotating and - revert shift after rotation. This preserves the bounds of the - space. + Interpolate values from map_3d_f onto 3D coordinates. Parameters ---------- @@ -434,18 +459,9 @@ def generate_slices(map_3d_f, xy_plane, rots): 0,0,0 pixel at map_3d_f[n/2,n/2,n/2] n_pix/2-1,n_pix/2-1,n_pix/2-1 pixel at the final corner, i.e. map_3d_f[n_pix-1,n_pix-1,n_pix-1] - xy_plane : arr - Array describing xy plane in space. - Shape (3, n_pix**2) - Convention x,y,z, i.e. - xy_plane[0] is x coordinate - xy_plane[1] is y coordinate - xy_plane[2] is z coordinate, which is all zero - n_pix : int - Number of pixels along one edge of the plane. - rots : arr - Array describing rotations. - Shape (n_rotations, n_pix**2, 3) + xyz_rotated : arr + Rotated xy planes. + Shape (n_rotations, 3, n_pix**2) Returns ------- @@ -453,9 +469,6 @@ def generate_slices(map_3d_f, xy_plane, rots): Slice of map_3d_f. Corresponds to Fourier transform of projection of rotated map_3d_f. Shape (n_rotations, n_pix, n_pix) - xyz_rotated : arr - Rotated xy planes. - Shape (n_rotations, 3, n_pix**2) Notes @@ -484,20 +497,130 @@ def generate_slices(map_3d_f, xy_plane, rots): As far as the presence of noise in the edge pixels, masking that crops close enough to the centre will keeping a safe distance from the edge. """ - n_rotations = len(rots) + n_rotations = len(xyz_rotated) n_pix = len(map_3d_f) - slices = np.empty((n_rotations, n_pix, n_pix)) - overwrite_empty_with_zero = 0 - slices[:, :, 0] = overwrite_empty_with_zero - xyz_rotated = np.empty((n_rotations, 3, n_pix**2)) + slices = np.empty((n_rotations, n_pix, n_pix), dtype=float) for i in range(n_rotations): - xyz_rotated[i] = rots[i] @ xy_plane - - slices[i] = map_coordinates(map_3d_f, xyz_rotated[i] + n_pix // 2).reshape( + slices[i] = map_coordinates( + map_3d_f.real, + xyz_rotated[i] + n_pix // 2, + ).reshape((n_pix, n_pix)) + 1j * map_coordinates( + map_3d_f.imag, + xyz_rotated[i] + n_pix // 2, + ).reshape( (n_pix, n_pix) ) + return slices + + @staticmethod + def pad_and_rotate_xy_planes(xy_plane, rots, n_pix, z_offset=0.05): + """Rotate xy planes after padding them in z symmetrically by z_offset. + + Parameters + ---------- + xy_plane : arr + Array describing xy plane in space. + Shape (3, n_pix**2) + Convention x,y,z, i.e. + xy_plane[0] is x coordinate + xy_plane[1] is y coordinate + xy_plane[2] is z coordinate, which is all zero + rots : arr + Array describing rotations. + Shape (n_rotations, n_pix**2, 3) + n_pix : int + Number of pixels per axis. + z_offset : float + Symmetrical z-depth given to the xy_plane before rotating. + 0 < z_offset < 1 + + Returns + ------- + xyz_rotated : arr + Rotated xy planes, padded on either side by z_offset. + Shape (n_rotations, 3, 3 * n_pix**2) + """ + n_rotations = len(rots) + offset = np.array( + [ + [0, 0, z_offset], + ] + ).T + xy_plane_padded = np.concatenate( + (xy_plane + offset, xy_plane, xy_plane - offset), axis=1 + ) + xyz_rotated_padded = np.empty((n_rotations, 3, 3 * n_pix**2)) + for i in range(n_rotations): + xyz_rotated_padded[i] = rots[i] @ xy_plane_padded + return xyz_rotated_padded + + @staticmethod + def insert_slice(slice_real, xy_rotated, xyz): + """Rotate slice and interpolate onto a 3D grid. + + Rotated xy-planes are expected to be of nonzero depth (i.e. a rotated + 2D plane with some small added z-depth to give "volume" to the slice in + order for interpolation to be feasible). The slice values are constant + along the depth axis of the slice. + + Parameters + ---------- + slice_real : float64 arr + Shape (n_pix, n_pix) the slice of interest. + xy_rotated : arr + Shape (3, 3*n_pix**2) nonzero-depth "plane" of rotated slice coords. + xyz : arr + Shape (3, n_pix**3) voxels of 3D map. + + Returns + ------- + inserted_slice_3d : float64 arr + Rotated slice in 3D voxel array. + Shape (n_pix, n_pix, n_pix) + count_3d : arr + Voxel array to count slice presence. + Shape (n_pix, n_pix, n_pix) + """ + n_pix = slice_real.shape[0] + slice_values = np.tile(slice_real.reshape((n_pix**2,)), (3,)) + + inserted_slice_3d = griddata( + xy_rotated.T, slice_values, xyz.T, fill_value=0, method="linear" + ).reshape((n_pix, n_pix, n_pix)) + + count_3d = griddata( + xy_rotated.T, + np.ones_like(slice_values), + xyz.T, + fill_value=0, + method="linear", + ).reshape((n_pix, n_pix, n_pix)) + + return inserted_slice_3d, count_3d - return slices, xyz_rotated + def insert_slice_v(self, slices_real, xy_rots, xyz): + """Vectorized version of insert_slice. + + Parameters + ---------- + slices_real : float64 arr + Shape (n_slices, n_pix, n_pix) the slices of interest. + xy_rots : arr + Shape (n_slices, 3, 3*n_pix**2) nonzero-depth "planes" of rotated + slice coords. + xyz : arr + Shape (3, n_pix**3) voxels of 3D map. + + Returns + ------- + inserted_slices_3d : float64 arr + Rotated slices in 3D voxel arrays. + Shape (n_slices, n_pix, n_pix, n_pix) + counts_3d : arr + Voxel array to count slice presence. + Shape (n_slices, n_pix, n_pix, n_pix) + """ + return self.insert_slice_vectorized(slices_real, xy_rots, xyz) @staticmethod def apply_ctf_to_slice(particle_slice, ctf): @@ -675,35 +798,6 @@ def compute_ssnr(projections_f, ctfs, small_number=0.01): return IterativeRefinement.expand_1d_to_nd(ssnr_1d, d=2) - @staticmethod - def insert_slice(slice_real, xyz, n_pix): - """Rotate slice and interpolate onto a 3D grid. - - Parameters - ---------- - slice_real : float64 arr - Shape (n_pix, n_pix) the slice of interest. - xyz : arr - Shape (n_pix**2, 3) plane corresponding to slice rotation. - n_pix : int - Number of pixels. - - Returns - ------- - inserted_slice_3d : float64 arr - Rotated slice in 3D voxel array. - Shape (n_pix, n_pix, n_pix) - count_3d : arr - Voxel array to count slice presence: 1 if slice present, - otherwise 0. - Shape (n_pix, n_pix, n_pix) - """ - shape = len(xyz) - count_3d = np.ones((n_pix, n_pix, n_pix)) - count_3d[0, 0, 0] *= shape - inserted_slice_3d = np.ones((n_pix, n_pix, n_pix)) - return inserted_slice_3d, count_3d - @staticmethod def compute_fsc(map_3d_f_1, map_3d_f_2): """Compute the Fourier shell correlation. diff --git a/tests/test_expectation_maximization.py b/tests/test_expectation_maximization.py index fa49c25..deb40b0 100644 --- a/tests/test_expectation_maximization.py +++ b/tests/test_expectation_maximization.py @@ -76,20 +76,56 @@ def test_grid_SO3_uniform(test_ir, n_particles): rots = test_ir.grid_SO3_uniform(n_particles) assert rots.shape == (n_particles, 3, 3) + rot = test_ir.grid_SO3_uniform(1) + assert rot.shape == (1, 3, 3) -def test_generate_xy_plane(test_ir, n_pix): - """Test generation of xy plane.""" - xy_plane = test_ir.generate_xy_plane(n_pix) + +def test_generate_cartesian_grid(test_ir, n_pix): + """Test generation of xy plane and xyz cube.""" + xy_plane = test_ir.generate_cartesian_grid(n_pix, 2) assert xy_plane.shape == (3, n_pix**2) n_pix_2 = 2 plane_2 = np.array([[-1, 0, -1, 0], [-1, -1, 0, 0], [0, 0, 0, 0]]) - xy_plane = test_ir.generate_xy_plane(n_pix_2) + xy_plane = test_ir.generate_cartesian_grid(n_pix_2, 2) assert np.allclose(xy_plane, plane_2) assert np.isclose(xy_plane.max(), n_pix_2 // 2 - 1) assert np.isclose(xy_plane.min(), -n_pix_2 // 2) + xyz_cube = test_ir.generate_cartesian_grid(n_pix, 3) + assert xyz_cube.shape == (3, n_pix**3) + + n_pix_2 = 2 + cube_2 = np.array( + [ + [-1, -1, -1, -1, 0, 0, 0, 0], + [-1, -1, 0, 0, -1, -1, 0, 0], + [-1, 0, -1, 0, -1, 0, -1, 0], + ] + ) + + xyz_cube = test_ir.generate_cartesian_grid(n_pix_2, 3) + assert np.allclose(xyz_cube, cube_2) + assert np.isclose(xyz_cube.max(), n_pix_2 // 2 - 1) + assert np.isclose(xyz_cube.min(), -n_pix_2 // 2) + + exceptionThrown = False + try: + test_ir.generate_cartesian_grid(n_pix, 4) + except ValueError: + exceptionThrown = True + assert exceptionThrown + + +def test_pad_and_rotate_xy_plane(test_ir, n_pix, n_particles): + """Test shape after padding and rotating xy plane.""" + n_rotations = n_particles + xy_plane = test_ir.generate_cartesian_grid(n_pix, 2) + rots = test_ir.grid_SO3_uniform(n_rotations) + xyz_rotated_padded = test_ir.pad_and_rotate_xy_planes(xy_plane, rots, n_pix) + assert xyz_rotated_padded.shape == (n_rotations, 3, 3 * n_pix**2) + def test_generate_slices(test_ir, n_particles, n_pix): """Test generation of slices. @@ -115,16 +151,19 @@ def test_generate_slices(test_ir, n_particles, n_pix): """ map_3d = np.ones((n_pix, n_pix, n_pix)) rots = test_ir.grid_SO3_uniform(n_particles) - xy_plane = test_ir.generate_xy_plane(n_pix) - slices, xyz_rotated_planes = test_ir.generate_slices(map_3d, xy_plane, rots) + xy_plane = test_ir.generate_cartesian_grid(n_pix, 2) + xyz_rotated_padded = test_ir.pad_and_rotate_xy_planes(xy_plane, rots, n_pix) + xyz_rotated = xyz_rotated_padded[:, :, n_pix**2 : 2 * n_pix**2] + slices = test_ir.generate_slices(map_3d, xyz_rotated) + assert slices.shape == (n_particles, n_pix, n_pix) - assert xyz_rotated_planes.shape == (n_particles, 3, n_pix**2) + assert xyz_rotated_padded.shape == (n_particles, 3, 3 * n_pix**2) map_3d_dc = np.zeros((n_pix, n_pix, n_pix)) rand_val = np.random.uniform(low=1, high=2) map_3d_dc[n_pix // 2, n_pix // 2, n_pix // 2] = rand_val expected_dc = rand_val * np.ones(len(slices)) - slices, xyz_rotated_planes = test_ir.generate_slices(map_3d_dc, xy_plane, rots) + slices = test_ir.generate_slices(map_3d_dc, xyz_rotated) projected_dc = slices[:, n_pix // 2, n_pix // 2] assert np.allclose(projected_dc, expected_dc) @@ -141,9 +180,12 @@ def test_generate_slices(test_ir, n_particles, n_pix): expected_slice_line_y = np.zeros_like(slices[0]) expected_slice_line_y[n_pix // 2] = 1 - slices, xyz_rotated_planes = test_ir.generate_slices( - map_plane_ones_xzplane, xy_plane, rot_90deg_about_y + xyz_rotated_padded = test_ir.pad_and_rotate_xy_planes( + xy_plane, rot_90deg_about_y, n_pix ) + xyz_rotated = xyz_rotated_padded[:, :, n_pix**2 : 2 * n_pix**2] + + slices = test_ir.generate_slices(map_plane_ones_xzplane, xyz_rotated) omit_idx_artefact = 1 assert np.allclose( slices[0, omit_idx_artefact:, omit_idx_artefact:], @@ -158,9 +200,13 @@ def test_generate_slices(test_ir, n_particles, n_pix): map_plane_ones_xyplane = np.zeros((n_pix, n_pix, n_pix)) map_plane_ones_xyplane[:, :, n_pix // 2] = 1 expected_slice = np.ones((n_pix, n_pix)) - slices, xyz_rotated_planes = test_ir.generate_slices( - map_plane_ones_xyplane, xy_plane, rot_180deg_about_z + + xyz_rotated_padded = test_ir.pad_and_rotate_xy_planes( + xy_plane, rot_180deg_about_z, n_pix ) + xyz_rotated = xyz_rotated_padded[:, :, n_pix**2 : 2 * n_pix**2] + + slices = test_ir.generate_slices(map_plane_ones_xyplane, xyz_rotated) assert np.allclose( slices[0, omit_idx_artefact:, omit_idx_artefact:], expected_slice[omit_idx_artefact:, omit_idx_artefact:], @@ -241,13 +287,63 @@ def test_apply_wiener_filter(test_ir, n_pix): def test_insert_slice(test_ir, n_pix): - """Test insertion of particle slice.""" - particle_slice = np.ones((n_pix, n_pix)) - xyz = test_ir.generate_xy_plane(n_pix) + """Test insertion of particle slice. + + Pull a slice out, put it back in. See if it's the same. + """ + xy_plane = test_ir.generate_cartesian_grid(n_pix, 2) + map_plane_ones = np.zeros((n_pix, n_pix, n_pix)) + map_plane_ones[n_pix // 2] = np.ones((n_pix, n_pix)) + + rot_90deg_about_y = np.array( + [ + [[0, 0, 1], [0, 1, 0], [-1, 0, 0]], + ] + ) + + xyz_rotated_padded = test_ir.pad_and_rotate_xy_planes( + xy_plane, rot_90deg_about_y, n_pix + ) + + slices = test_ir.generate_slices( + map_plane_ones, xyz_rotated_padded[:, :, n_pix**2 : 2 * n_pix**2] + ) + + xyz_voxels = test_ir.generate_cartesian_grid(n_pix, 3) + + inserted, count = test_ir.insert_slice(slices[0], xyz_rotated_padded[0], xyz_voxels) + + omit_idx_artefact = 1 + + assert np.allclose( + inserted[omit_idx_artefact:, omit_idx_artefact:, omit_idx_artefact:], + map_plane_ones[omit_idx_artefact:, omit_idx_artefact:, omit_idx_artefact:], + ) + assert np.allclose( + count[omit_idx_artefact:, omit_idx_artefact:, omit_idx_artefact:], + map_plane_ones[omit_idx_artefact:, omit_idx_artefact:, omit_idx_artefact:], + ) + + +def test_insert_slice_v(test_ir, n_pix): + """Test whether vectorized insert_slice produces the right shapes.""" + n_slices = 5 + xy_plane = test_ir.generate_cartesian_grid(n_pix, 2) + z_tol = np.array( + [ + [0, 0, 0.05], + ] + ).T + xy_plane_tol = np.concatenate( + (xy_plane + z_tol, xy_plane, xy_plane - z_tol), axis=1 + ) + test_slices = np.ones((n_slices, n_pix, n_pix)) + xy_planes_tol = np.tile(np.expand_dims(xy_plane_tol, axis=0), (n_slices, 1, 1)) + xyz = test_ir.generate_cartesian_grid(n_pix, 3) - inserted, count = test_ir.insert_slice(particle_slice, xyz, n_pix) - assert inserted.shape == (n_pix, n_pix, n_pix) - assert count.shape == (n_pix, n_pix, n_pix) + inserts, counts = test_ir.insert_slice_v(test_slices, xy_planes_tol, xyz) + assert inserts.shape == (n_slices, n_pix, n_pix, n_pix) + assert counts.shape == (n_slices, n_pix, n_pix, n_pix) def test_compute_fsc(test_ir, n_pix):