Note
Go to the end to download the full example code or to run this example in your browser via Binder.
Learn Sampling pattern for multi-coil MRI#
A small pytorch example to showcase learning k-space sampling patterns. This example showcases the auto-diff capabilities of the NUFFT operator wrt to k-space trajectory in mri-nufft.
Briefly, in this example we try to learn the k-space samples \(\mathbf{K}\) for the following cost function:
where \(S_\ell\) is the sensitivity map for the \(\ell\)-th coil, \(\mathcal{F}_\mathbf{K}\) is the forward NUFFT operator and \(D_\mathbf{K}\) is the density compensators for trajectory \(\mathbf{K}\), \(\mathbf{x}_\ell\) is the image for the \(\ell\)-th coil, and \(\mathbf{x}_{sos} = \sqrt{\sum_{\ell=1}^L x_\ell^2}\) is the sum-of-squares image as target image to be reconstructed.
In this example, the forward NUFFT operator \(\mathcal{F}_\mathbf{K}\) is implemented with model.operator while the SENSE operator model.sense_op models the term \(\mathbf{A} = \sum_{\ell=1}^LS_\ell^* \mathcal{F}_\mathbf{K}^* D_\mathbf{K}\).
For our data, we use a 2D slice of a 3D MRI image from the BrainWeb dataset, and the sensitivity maps are simulated using the birdcage_maps function from sigpy.mri.
Note
To showcase the features of mri-nufft, we use ``
“cufinufft”`` backend for model.operator without density compensation and "gpunufft" backend for model.sense_op with density compensation.
Warning
This example only showcases the autodiff capabilities, the learned sampling pattern is not scanner compliant as the scanner gradients required to implement it violate the hardware constraints. In practice, a projection \(\Pi_\mathcal{Q}(\mathbf{K})\) into the scanner constraints set \(\mathcal{Q}\) is recommended (see [Proj]). This is implemented in the proprietary SPARKLING package [Sparks]. Users are encouraged to contact the authors if they want to use it.
Imports#
import os
import brainweb_dl as bwdl
import matplotlib.pyplot as plt
import numpy as np
import torch
import matplotlib.animation as animation
from mrinufft import get_operator
from mrinufft.extras import get_smaps
from mrinufft.trajectories import initialize_2D_radial
from sigpy.mri import birdcage_maps
/volatile/github-ci-mind-inria/gpu_mind_runner/_work/mri-nufft/mri-nufft/.venv/lib/python3.12/site-packages/cupyx/jit/_interface.py:247: FutureWarning: cupyx.jit.rawkernel is experimental. The interface can change in the future.
cupy._util.experimental('cupyx.jit.rawkernel')
Setup a simple class to learn trajectory#
Note
While we are only learning the NUFFT operator, we still need the gradient wrt_data=True to have all the gradients computed correctly. See [Projector] for more details.
BACKEND = os.environ.get("MRINUFFT_BACKEND", "cufinufft")
plt.rcParams["animation.embed_limit"] = 2**30 # 1GiB is very large.
class Model(torch.nn.Module):
def __init__(self, inital_trajectory, n_coils, img_size=(256, 256)):
super(Model, self).__init__()
self.trajectory = torch.nn.Parameter(
data=torch.Tensor(inital_trajectory),
requires_grad=True,
)
sample_points = inital_trajectory.reshape(-1, inital_trajectory.shape[-1])
# A simple acquisition model simulated with a forward NUFFT operator. We dont need density compensation here.
# The trajectory is scaled by 2*pi for cufinufft backend.
self.operator = get_operator(BACKEND, wrt_data=True, wrt_traj=True)(
sample_points * 2 * np.pi,
shape=img_size,
n_coils=n_coils,
squeeze_dims=False,
)
# A simple density compensated adjoint SENSE operator with sensitivity maps `smaps`.
self.sense_op = get_operator(BACKEND, wrt_data=True, wrt_traj=True)(
sample_points,
shape=img_size,
density=True,
n_coils=n_coils,
smaps=np.ones(
(n_coils, *img_size), dtype=np.complex64
), # Dummy smaps, this is updated in forward pass
squeeze_dims=False,
)
self.img_size = img_size
def forward(self, x):
"""Forward pass of the model."""
# Update the trajectory in the NUFFT operator.
# The trajectory is scaled by 2*pi for cufinufft backend.
# Note that the re-computation of density compensation happens internally.
self.operator.samples = self.trajectory.clone() * 2 * np.pi
self.sense_op.samples = self.trajectory.clone()
# Simulate the acquisition process
kspace = self.operator.op(x)
# Recompute the sensitivity maps for the updated trajectory.
self.sense_op.smaps = get_smaps("low_frequency")(
self.trajectory.detach().numpy(),
self.img_size,
kspace.detach(),
backend=BACKEND,
density=self.sense_op.density,
blurr_factor=20,
)
# Reconstruction using the sense operator
adjoint = self.sense_op.adj_op(kspace).abs()
return adjoint / torch.mean(adjoint)
Setup model and optimizer#
num_epochs = 100
n_coils = 6
init_traj = (
initialize_2D_radial(32, 256).astype(np.float32).reshape(-1, 2).astype(np.float32)
)
model = Model(init_traj, n_coils=n_coils, img_size=(256, 256))
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
schedulder = torch.optim.lr_scheduler.LinearLR(
optimizer,
start_factor=1,
end_factor=0.1,
total_iters=num_epochs,
)
Setup data#
mri_2D = torch.from_numpy(np.flipud(bwdl.get_mri(4, "T1")[80, ...]).astype(np.float32))
mri_2D = mri_2D / torch.mean(mri_2D)
smaps_simulated = torch.from_numpy(birdcage_maps((n_coils, *mri_2D.shape)))
mcmri_2D = mri_2D[None].to(torch.complex64) * smaps_simulated
model.eval()
recon = model(mcmri_2D)
W0826 12:21:25.518000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
0%| | 0/10 [00:00<?, ?it/s]
50%|█████ | 5/10 [00:00<00:00, 45.92it/s]
100%|██████████| 10/10 [00:00<00:00, 35.00it/s]
100%|██████████| 10/10 [00:00<00:00, 36.27it/s]
Training and plotting#
fig, axs = plt.subplots(2, 2, figsize=(10, 10))
fig.suptitle("Training Starting")
axs = axs.flatten()
axs[0].imshow(np.abs(mri_2D), cmap="gray")
axs[0].axis("off")
axs[0].set_title("MR Image")
traj_scat = axs[1].scatter(*init_traj.T, s=0.5)
axs[1].set_title("Trajectory")
recon_im = axs[2].imshow(np.abs(recon.squeeze().detach().cpu().numpy()), cmap="gray")
axs[2].axis("off")
axs[2].set_title("Reconstruction")
(loss_curve,) = axs[3].plot([], [])
axs[3].grid()
axs[3].set_xlabel("epochs")
axs[3].set_ylabel("loss")
fig.tight_layout()
def train():
"""Train loop."""
losses = []
for i in range(num_epochs):
out = model(mcmri_2D)
loss = torch.nn.functional.mse_loss(out, mri_2D[None, None]) # Compute loss
optimizer.zero_grad() # Zero gradients
loss.backward() # Backward pass
optimizer.step() # Update weights
with torch.no_grad():
# clamp the value of trajectory between [-0.5, 0.5]
for param in model.parameters():
param.clamp_(-0.5, 0.5)
schedulder.step()
losses.append(loss.item())
yield (
out.detach().cpu().numpy().squeeze(),
model.trajectory.detach().cpu().numpy(),
losses,
)
def plot_epoch(data):
img, traj, losses = data
cur_epoch = len(losses)
recon_im.set_data(abs(img))
loss_curve.set_xdata(np.arange(cur_epoch))
loss_curve.set_ydata(losses)
traj_scat.set_offsets(traj)
axs[3].set_xlim(0, cur_epoch)
axs[3].set_ylim(0, 1.1 * max(losses))
axs[2].set_title(f"Reconstruction, frame {cur_epoch}/{num_epochs}")
axs[1].set_title(f"Trajectory, frame {cur_epoch}/{num_epochs}")
if cur_epoch < num_epochs:
fig.suptitle("Training in progress " + "." * (1 + cur_epoch % 3))
else:
fig.suptitle("Training complete !")
ani = animation.FuncAnimation(
fig, plot_epoch, train, save_count=num_epochs, repeat=False
)
plt.show()
/volatile/github-ci-mind-inria/gpu_mind_runner/_work/mri-nufft/mri-nufft/examples/GPU/example_learn_samples_multicoil.py:151: DeprecationWarning: __array_wrap__ must accept context and return_scalar arguments (positionally) in the future. (Deprecated NumPy 2.0)
axs[0].imshow(np.abs(mri_2D), cmap="gray")
W0826 12:21:26.360000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:27.138000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:28.104000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:29.208000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:30.347000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:31.466000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:32.572000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:33.556000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:34.557000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:35.557000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:36.548000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:37.503000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:38.450000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:39.402000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:40.364000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:41.319000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:42.271000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:43.244000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:44.202000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:45.150000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:46.110000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:47.062000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:48.119000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:49.089000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:50.028000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:50.865000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:51.725000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:52.673000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:53.664000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:54.635000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:55.650000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:56.645000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:57.657000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:58.575000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:21:59.498000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:00.459000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:01.347000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:02.257000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:03.099000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:03.927000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:04.761000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:05.583000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:06.454000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:07.304000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:08.128000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:08.984000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:09.832000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:10.670000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:11.499000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:12.331000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:13.160000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:14.024000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:14.857000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:15.767000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:16.625000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:17.486000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:18.316000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:19.231000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:20.065000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:20.890000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:21.710000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:22.570000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:23.400000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:24.213000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:25.039000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:25.927000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:26.786000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:27.663000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:28.506000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:29.396000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:30.239000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:31.090000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:32.002000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:32.891000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:33.780000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:34.665000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:35.508000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:36.331000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:37.175000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:38.015000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:38.864000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:39.709000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:40.600000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:41.478000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:42.341000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:43.178000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:44.024000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:44.883000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:45.702000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:46.600000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:47.459000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:48.302000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:49.138000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:49.967000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:50.887000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:51.851000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:52.824000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:53.831000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:54.688000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:55.515000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:56.362000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:57.611000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:58.160000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:59.063000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:22:59.928000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:00.834000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:01.733000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:02.613000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:03.490000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:04.361000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:05.252000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:06.107000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:06.962000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:07.863000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:08.719000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:09.577000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:10.428000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:11.337000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:12.196000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:13.099000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:14.026000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:14.884000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:15.782000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:16.635000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:17.564000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:18.417000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:19.265000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:20.177000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:21.026000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:21.888000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:22.745000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:23.627000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:24.504000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:25.342000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:26.206000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:27.110000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:27.962000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:28.834000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:29.740000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:30.608000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:31.478000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:32.321000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:33.226000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:34.085000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:34.958000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:35.841000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:36.732000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:37.580000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:38.391000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:39.256000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:40.101000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:40.913000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:41.792000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:42.660000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:43.496000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:44.326000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:45.140000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:46.037000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:46.883000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:47.698000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:48.577000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:49.428000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:50.247000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:51.080000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:51.969000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:52.796000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:53.623000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:54.442000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:55.339000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:56.165000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:56.999000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:57.875000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:58.718000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:23:59.555000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:00.411000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:01.248000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:02.083000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:02.912000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:03.732000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:04.607000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:05.443000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:06.264000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:07.131000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:08.006000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:08.835000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:09.681000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:10.513000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:11.412000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:12.251000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:13.074000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:13.957000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:14.801000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:15.636000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:16.491000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:17.346000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:18.158000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:18.990000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:19.798000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:20.679000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:21.502000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:22.328000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
W0826 12:24:23.185000 1773124 mri-nufft/src/mrinufft/_array_compat.py:265] _call_impl: data is on gpu, it will be moved to CPU.
References#
N. Chauffert, P. Weiss, J. Kahn and P. Ciuciu, “A Projection Algorithm for Gradient Waveforms Design in Magnetic Resonance Imaging,” in IEEE Transactions on Medical Imaging, vol. 35, no. 9, pp. 2026-2039, Sept. 2016, doi: 10.1109/TMI.2016.2544251.
G. R. Chaithya, P. Weiss, G. Daval-Frérot, A. Massire, A. Vignaud and P. Ciuciu, “Optimizing Full 3D SPARKLING Trajectories for High-Resolution Magnetic Resonance Imaging,” in IEEE Transactions on Medical Imaging, vol. 41, no. 8, pp. 2105-2117, Aug. 2022, doi: 10.1109/TMI.2022.3157269.
Chaithya GR, and Philippe Ciuciu. 2023. “Jointly Learning Non-Cartesian k-Space Trajectories and Reconstruction Networks for 2D and 3D MR Imaging through Projection” Bioengineering 10, no. 2: 158. https://doi.org/10.3390/bioengineering10020158
Total running time of the script: (3 minutes 5.037 seconds)