Beispiel #1
0
def unique_coords_nd(N, ndim, shifted=False, normalized=True):
    """
    Generate unique polar coordinates from 2D or 3D rectangular coordinates.
    :param N: length size of a square or cube.
    :param ndim: number of dimension, 2 or 3.
    :param shifted: shifted half pixel or not for odd N.
    :param normalized: normalize the grid or not.
    :return: The unique polar coordinates in 2D or 3D
    """
    ensure(ndim in (2, 3),
           'Only two- or three-dimensional basis functions are supported.')
    ensure(N > 0, 'Number of grid points should be greater than 0.')

    if ndim == 2:
        grid = grid_2d(N, shifted=shifted, normalized=normalized)
        mask = grid['r'] <= 1

        # Minor differences in r/theta/phi values are unimportant for the purpose
        # of this function, so round off before proceeding

        # TODO: numpy boolean indexing will return a 1d array (like MATLAB)
        # However, it always searches in row-major order, unlike MATLAB (column-major),
        # with no options to change the search order. The results we'll be getting back are thus not comparable.
        # We transpose the appropriate ndarrays before applying the mask to obtain the same behavior as MATLAB.
        r = grid['r'].T[mask].round(5)
        phi = grid['phi'].T[mask].round(5)

        r_unique, r_idx = np.unique(r, return_inverse=True)
        ang_unique, ang_idx = np.unique(phi, return_inverse=True)

    else:
        grid = grid_3d(N, shifted=shifted, normalized=normalized)
        mask = grid['r'] <= 1

        # In Numpy, elements in the indexed array are always iterated and returned in row-major (C-style) order.
        # To emulate a behavior where iteration happens in Fortran order, we swap axes 0 and 2 of both the array
        # being indexed (r/theta/phi), as well as the mask itself.
        # TODO: This is only for the purpose of getting the same behavior as MATLAB while porting the code, and is
        # likely not needed in the final version.

        # Minor differences in r/theta/phi values are unimportant for the purpose of this function,
        # so we round off before proceeding.

        mask_ = np.swapaxes(mask, 0, 2)
        r = np.swapaxes(grid['r'], 0, 2)[mask_].round(5)
        theta = np.swapaxes(grid['theta'], 0, 2)[mask_].round(5)
        phi = np.swapaxes(grid['phi'], 0, 2)[mask_].round(5)

        r_unique, r_idx = np.unique(r, return_inverse=True)
        ang_unique, ang_idx = np.unique(np.vstack([theta, phi]),
                                        axis=1,
                                        return_inverse=True)

    return {
        'r_unique': r_unique,
        'ang_unique': ang_unique,
        'r_idx': r_idx,
        'ang_idx': ang_idx,
        'mask': mask
    }
Beispiel #2
0
 def testGrid3d(self):
     grid3d = grid_3d(8)
     self.assertTrue(np.allclose(grid3d['x'], np.load(os.path.join(DATA_DIR, 'grid3d_8_x.npy'))))
     self.assertTrue(np.allclose(grid3d['y'], np.load(os.path.join(DATA_DIR, 'grid3d_8_y.npy'))))
     self.assertTrue(np.allclose(grid3d['z'], np.load(os.path.join(DATA_DIR, 'grid3d_8_z.npy'))))
     self.assertTrue(np.allclose(grid3d['r'], np.load(os.path.join(DATA_DIR, 'grid3d_8_r.npy'))))
     self.assertTrue(np.allclose(grid3d['phi'], np.load(os.path.join(DATA_DIR, 'grid3d_8_phi.npy'))))
     self.assertTrue(np.allclose(grid3d['theta'], np.load(os.path.join(DATA_DIR, 'grid3d_8_theta.npy'))))
Beispiel #3
0
    def testDownsample(self):
        # generate a 3D map with density decays as Gaussian function
        g3d = grid_3d(self.L, dtype=self.dtype)
        coords = np.array(
            [g3d["x"].flatten(), g3d["y"].flatten(), g3d["z"].flatten()])
        sigma = 0.2
        vol = np.exp(-0.5 * np.sum(np.abs(coords / sigma)**2, axis=0)).astype(
            self.dtype)
        vol = np.reshape(vol, g3d["x"].shape)
        vols = Volume(vol)

        # set noise to zero and CFT filters to unity for simulation object
        noise_var = 0
        noise_filter = ScalarFilter(dim=2, value=noise_var)
        sim = Simulation(
            L=self.L,
            n=self.n,
            vols=vols,
            offsets=0.0,
            amplitudes=1.0,
            unique_filters=[
                ScalarFilter(dim=2, value=1)
                for d in np.linspace(1.5e4, 2.5e4, 7)
            ],
            noise_filter=noise_filter,
            dtype=self.dtype,
        )
        # get images before downsample
        imgs_org = sim.images(start=0, num=self.n)
        # get images after downsample
        max_resolution = 32
        sim.downsample(max_resolution)
        imgs_ds = sim.images(start=0, num=self.n)

        # Check individual grid points
        self.assertTrue(
            np.allclose(
                imgs_org[:, 32, 32],
                imgs_ds[:, 16, 16],
                atol=utest_tolerance(self.dtype),
            ))
        # check resolution
        self.assertTrue(np.allclose(max_resolution, imgs_ds.shape[1]))
        # check energy conservation after downsample
        self.assertTrue(
            np.allclose(
                anorm(imgs_org.asnumpy(), axes=(1, 2)) / self.L,
                anorm(imgs_ds.asnumpy(), axes=(1, 2)) / max_resolution,
                atol=utest_tolerance(self.dtype),
            ))
Beispiel #4
0
    def eval_gaussian_blobs(self, L, Q, D, mu):
        g = grid_3d(L)
        coords = np.array(
            [g['x'].flatten(), g['y'].flatten(), g['z'].flatten()])

        K = Q.shape[-1]
        vol = np.zeros(shape=(1, coords.shape[-1])).astype(self.dtype)

        for k in range(K):
            coords_k = coords - mu[:, k, np.newaxis]
            coords_k = Q[:, :, k] / np.sqrt(np.diag(
                D[:, :, k])) @ Q[:, :, k].T @ coords_k

            vol += np.exp(-0.5 * np.sum(np.abs(coords_k)**2, axis=0))

        vol = np.reshape(vol, g['x'].shape)

        return vol
Beispiel #5
0
    def eval_gaussian_blobs(self, L, Q, D, mu):
        g = grid_3d(L)
        # Migration Note - Matlab (:) flattens in column-major order, so specify 'F' with flatten()
        coords = np.array(
            [g['x'].flatten('F'), g['y'].flatten('F'), g['z'].flatten('F')])

        K = Q.shape[-1]
        vol = np.zeros(shape=(1, coords.shape[-1])).astype(self.dtype)

        for k in range(K):
            coords_k = coords - mu[:, k, np.newaxis]
            coords_k = Q[:, :, k] / np.sqrt(np.diag(
                D[:, :, k])) @ Q[:, :, k].T @ coords_k

            vol += np.exp(-0.5 * np.sum(np.abs(coords_k)**2, axis=0))

        vol = m_reshape(vol, g['x'].shape)

        return vol
def downsample(insamples, szout):
    """
    Blur and downsample 1D to 3D objects such as, curves, images or volumes
    :param insamples: Set of objects to be downsampled in the form of an array, the last dimension
                    is the number of objects.
    :param szout: The desired resolution of for output objects.
    :return: An array consists of the blurred and downsampled objects.
    """

    ensure(
        insamples.ndim - 1 == szout.ndim,
        'The number of downsampling dimensions is not the same as that of objects.'
    )

    L_in = insamples.shape[0]
    L_out = szout.shape[0]
    ndata = insamples.shape(-1)
    outdims = szout
    outdims.push_back(ndata)
    outsamples = np.zeros((outdims)).astype(insamples.dtype)

    if insamples.ndim == 2:
        # one dimension object
        grid_in = grid_1d(L_in)
        grid_out = grid_1d(L_out)
        # x values corresponding to 'grid'. This is what scipy interpolator needs to function.
        x = np.ceil(np.arange(-L_in / 2, L_in / 2)) / (L_in / 2)
        mask = (np.abs(grid_in['x']) < L_out / L_in)
        insamples_fft = np.real(
            centered_ifft1(centered_fft1(insamples) * np.expand_dims(mask, 1)))
        for idata in range(ndata):
            interpolator = RegularGridInterpolator((x, ),
                                                   insamples_fft[:, idata],
                                                   bounds_error=False,
                                                   fill_value=0)
            outsamples[:, :, idata] = interpolator(np.dstack([grid_out['x']]))

    elif insamples.ndim == 3:
        grid_in = grid_2d(L_in)
        grid_out = grid_2d(L_out)
        # x, y values corresponding to 'grid'. This is what scipy interpolator needs to function.
        x = y = np.ceil(np.arange(-L_in / 2, L_in / 2)) / (L_in / 2)
        mask = (np.abs(grid_in['x']) < L_out / L_in) & (np.abs(grid_in['y']) <
                                                        L_out / L_in)
        insamples_fft = np.real(
            centered_ifft2(centered_fft2(insamples) * np.expand_dims(mask, 2)))
        for idata in range(ndata):
            interpolator = RegularGridInterpolator((x, y),
                                                   insamples_fft[:, :, idata],
                                                   bounds_error=False,
                                                   fill_value=0)
            outsamples[:, :, idata] = interpolator(
                np.dstack([grid_out['x'], grid_out['y']]))

    elif insamples.ndim == 4:
        grid_in = grid_3d(L_in)
        grid_out = grid_3d(L_out)
        # x, y, z values corresponding to 'grid'. This is what scipy interpolator needs to function.
        x = y = z = np.ceil(np.arange(-L_in / 2, L_in / 2)) / (L_in / 2)
        mask = (np.abs(grid_in['x']) < L_out / L_in) & (np.abs(
            grid_in['y']) < L_out / L_in) & (np.abs(grid_in['z']) <
                                             L_out / L_in)
        insamples_fft = np.real(
            centered_ifft3(centered_fft3(insamples) * np.expand_dims(mask, 3)))
        for idata in range(ndata):
            interpolator = RegularGridInterpolator((x, y, z),
                                                   insamples_fft[:, :, :,
                                                                 idata],
                                                   bounds_error=False,
                                                   fill_value=0)
            outsamples[:, :, :, idata] = interpolator(
                np.dstack([grid_out['x'], grid_out['y'], grid_out['z']]))

    return outsamples