Source code for etomo.operators.fourier.utils

"""
Functions to transform data from radon space to fourier space (only in 2D for
now). Density compensation taken from pysap-mri.
"""
import numpy as np
import scipy.fftpack as pfft


[docs]def generate_locations_etomo_2D(size_x, angles): """ This function generates the list of the samples coordinate in the k-space. Parameters ---------- size_x: int image size along the x-axis angles: numpy.ndarray(q) array countaining the acquisition angles Returns ------- samples: numpy.ndarray((size_x * q, 2)) Fourier space locations generated from the given angles and data image size """ diag_x = int(np.floor(np.sqrt(2) * size_x)) rho = np.linspace(-0.5, 0.5, diag_x, endpoint=False) for t, angle in enumerate(angles): sample = np.zeros((diag_x, 2)) sample[:, 0] = rho * np.sin(angle * 1.0 * np.pi / 180.) sample[:, 1] = rho * np.cos(angle * 1.0 * np.pi / 180.) if t == 0: samples = sample else: samples = np.concatenate([samples, sample], axis=0) return samples
[docs]def generate_kspace_etomo_2D(sinogram): """ This function generates the list of the kspace observations. Parameters ---------- sinogram: numpy.ndarray((q, m)) sinogram with size nb_angles and size_x (m) Returns ------- kspace_obs: numpy.ndarray((q*int(m*sqrt(2))) Fourier space values from the given sinogram """ nb_angles, size_x = sinogram.shape diag_x = int(np.floor(np.sqrt(2) * size_x)) jmin = int(np.floor((np.floor(np.sqrt(2) * size_x) - size_x) / 2)) jmax = int(np.ceil((size_x - np.floor(np.sqrt(2) * size_x)) / 2)) sinograms_zp = np.zeros((nb_angles, diag_x)) sinograms_zp[:, jmin:jmax] = sinogram ft_sinogram = [] for t in range(sinogram.shape[0]): ft_sinogram = np.concatenate([ft_sinogram, pfft.fftshift(pfft.fft( pfft.ifftshift(sinograms_zp[t])))]) return np.real(ft_sinogram)
[docs]def estimate_density_compensation(kspace_loc, volume_shape, num_iterations=10): """ Utils function to obtain the density compensator for a given set of kspace locations. Parameters ---------- kspace_loc: numpy.ndarray the kspace locations volume_shape: numpy.ndarray the volume shape num_iterations: int, default 10 the number of iterations for density estimation """ from .fourier import gpuNUFFT grid_op = gpuNUFFT( samples=kspace_loc, shape=volume_shape, osf=1 ) density_comp = np.ones(kspace_loc.shape[0]) for _ in range(num_iterations): density_comp = ( density_comp / np.abs(grid_op.op(grid_op.adj_op(density_comp, True), True)) ) return density_comp