-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for density compensation (#109)
* Add support for density compensation * Fix Documentation and PEP8 * Update to utils.py and README * Update tests for sensitivity extraction * remove warning for pyNUFFT and make it an error * Update based on comments from Zac * Revert a single change to prevent unwanted changes * Final changes * Make den_c None in case not used * Fix Doc Co-authored-by: chaithyagr <[email protected]>
- Loading branch information
1 parent
b79a5da
commit d6acae5
Showing
9 changed files
with
332 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
examples/GPU_Examples/NonCartesian_gpuNUFFT_DensityCompensation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
""" | ||
Neuroimaging non-cartesian reconstruction | ||
========================================= | ||
Author: Chaithya G R | ||
In this tutorial we will reconstruct an MR Image directly with density | ||
compensation | ||
Import neuroimaging data | ||
------------------------ | ||
We use the toy datasets available in pysap, more specifically a 2D brain slice | ||
and the radial acquisition scheme (non-cartesian). | ||
""" | ||
|
||
# Package import | ||
from mri.operators import NonCartesianFFT, WaveletUD2 | ||
from mri.operators.utils import convert_locations_to_mask, \ | ||
gridded_inverse_fourier_transform_nd | ||
from mri.operators.fourier.utils import estimate_density_compensation | ||
from mri.reconstructors import SingleChannelReconstructor | ||
import pysap | ||
from pysap.data import get_sample_data | ||
|
||
# Third party import | ||
from modopt.math.metrics import ssim | ||
from modopt.opt.linear import Identity | ||
from modopt.opt.proximity import SparseThreshold | ||
import numpy as np | ||
|
||
# Loading input data | ||
image = get_sample_data('2d-mri') | ||
|
||
# Obtain MRI non-cartesian mask and estimate the density compensation | ||
radial_mask = get_sample_data("mri-radial-samples") | ||
kspace_loc = radial_mask.data | ||
density_comp = estimate_density_compensation(kspace_loc, image.shape) | ||
|
||
############################################################################# | ||
# Generate the kspace | ||
# ------------------- | ||
# | ||
# From the 2D brain slice and the acquisition mask, we retrospectively | ||
# undersample the k-space using a radial acquisition mask | ||
# We then reconstruct using adjoint with and without density compensation | ||
|
||
# Get the locations of the kspace samples and the associated observations | ||
fourier_op = NonCartesianFFT( | ||
samples=kspace_loc, | ||
shape=image.shape, | ||
implementation='gpuNUFFT', | ||
) | ||
fourier_op_density_comp = NonCartesianFFT( | ||
samples=kspace_loc, | ||
shape=image.shape, | ||
implementation='gpuNUFFT', | ||
density_comp=density_comp | ||
) | ||
# Get the kspace data retrospectively. Note that this can be done with | ||
# `fourier_op_density_comp` as the forward operator is the same | ||
kspace_obs = fourier_op.op(image.data) | ||
|
||
# Simple adjoint | ||
image_rec0 = pysap.Image(data=np.abs(fourier_op.adj_op(kspace_obs))) | ||
# image_rec0.show() | ||
base_ssim = ssim(image_rec0, image) | ||
print('The SSIM from Adjoint is : ' + str(base_ssim)) | ||
|
||
# Density Compensation adjoint: | ||
# This preconditions k-space giving a result closer to inverse | ||
image_rec1 = pysap.Image(data=np.abs( | ||
fourier_op_density_comp.adj_op(kspace_obs)) | ||
) | ||
# image_rec1.show() | ||
new_ssim = ssim(image_rec1, image) | ||
print('The SSIM from Density ' | ||
'compensated Adjoint is : ' + str(new_ssim)) |
86 changes: 86 additions & 0 deletions
86
examples/GPU_Examples/NonCartesian_gpuNUFFT_SENSE_DensityCompensation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
""" | ||
Neuroimaging non-cartesian reconstruction | ||
========================================= | ||
Author: Chaithya G R | ||
In this tutorial we will reconstruct an MR Image directly with density | ||
compensation and SENSE from gpuNUFFT | ||
Import neuroimaging data | ||
------------------------ | ||
We use the toy datasets available in pysap, more specifically a 3D orange data | ||
and the radial acquisition scheme (non-cartesian). | ||
""" | ||
|
||
# Package import | ||
from mri.operators import NonCartesianFFT, WaveletUD2 | ||
from mri.operators.utils import convert_locations_to_mask, \ | ||
gridded_inverse_fourier_transform_nd | ||
from mri.operators.fourier.utils import estimate_density_compensation | ||
from mri.reconstructors import SingleChannelReconstructor | ||
from mri.reconstructors.utils.extract_sensitivity_maps import get_Smaps | ||
import pysap | ||
from pysap.data import get_sample_data | ||
|
||
# Third party import | ||
from modopt.math.metrics import ssim | ||
from modopt.opt.linear import Identity | ||
from modopt.opt.proximity import SparseThreshold | ||
import numpy as np | ||
|
||
# Loading input data | ||
image = get_sample_data('3d-pmri') | ||
cartesian = np.linalg.norm(image, axis=0) | ||
|
||
# Obtain MRI non-cartesian mask and estimate the density compensation | ||
radial_mask = get_sample_data("mri-radial-3d-samples") | ||
kspace_loc = radial_mask.data | ||
density_comp = estimate_density_compensation(kspace_loc, cartesian.shape) | ||
|
||
############################################################################# | ||
# Generate the kspace | ||
# ------------------- | ||
# | ||
# From the 3D orange slice and 3D radial acquisition mask, we retrospectively | ||
# undersample the k-space | ||
# We then reconstruct using adjoint with and without density compensation | ||
|
||
# Get the locations of the kspace samples and the associated observations | ||
fourier_op = NonCartesianFFT( | ||
samples=kspace_loc, | ||
shape=cartesian.shape, | ||
n_coils=image.shape[0], | ||
implementation='gpuNUFFT', | ||
) | ||
kspace_obs = fourier_op.op(image.data) | ||
Smaps, SOS = get_Smaps( | ||
k_space=kspace_obs, | ||
img_shape=fourier_op.shape, | ||
samples=kspace_loc, | ||
thresh=(0.05, 0.05, 0.05), # The cutoff threshold in each kspace | ||
# direction between 0 and kspace_max (0.5) | ||
min_samples=kspace_loc.min(axis=0), | ||
max_samples=kspace_loc.max(axis=0), | ||
density_comp=density_comp, | ||
mode='NFFT', | ||
) | ||
fourier_op_sense_dc = NonCartesianFFT( | ||
samples=kspace_loc, | ||
shape=cartesian.shape, | ||
implementation='gpuNUFFT', | ||
n_coils=image.shape[0], | ||
density_comp=density_comp, | ||
smaps=Smaps, | ||
) | ||
|
||
# Density Compensation SENSE adjoint: | ||
# This preconditions k-space giving a result closer to inverse | ||
image_rec1 = pysap.Image(data=np.abs( | ||
fourier_op_sense_dc.adj_op(kspace_obs)) | ||
) | ||
# image_rec1.show() | ||
base_ssim = ssim(image_rec1, cartesian) | ||
print('The SSIM for simple Density ' | ||
'compensated SENSE Adjoint is : ' + str(base_ssim)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.