Open In Colab Download notebook

Different ways to obtain the trajectory

This example builds upon the Direct reconstruction of 2D golden angle radial data example and demonstrates three ways to obtain the trajectory information required for image reconstruction:

  • using the trajectory that is stored in the ISMRMRD file

  • calculating the trajectory using the radial 2D trajectory calculator

  • calculating the trajectory from the pulseq sequence file using the PyPulseq trajectory calculator

Hide code cell content
# Download raw data from Zenodo
import tempfile
from pathlib import Path

import mrpro
import torch
import zenodo_get

dataset = '14617082'

tmp = tempfile.TemporaryDirectory()  # RAII, automatically cleaned up
data_folder = Path(tmp.name)
zenodo_get.zenodo_get([dataset, '-r', 5, '-o', data_folder])  # r: retries

Using KTrajectoryIsmrmrd - Trajectory saved in ISMRMRD file

Passing an instance of KTrajectoryIsmrmrd to when loading the data tells the KData object to use the trajectory that is stored in the ISMRMRD file.

Note

Often the trajectory information has not been stored in the ISMRMRD file, in which case loading the trajectory this way will raise an error.

# Read the raw data and the trajectory from ISMRMRD file
kdata = mrpro.data.KData.from_file(
    data_folder / 'radial2D_402spokes_golden_angle_with_traj.h5',
    mrpro.data.traj_calculators.KTrajectoryIsmrmrd(),
)

# Reconstruct image
reconstruction = mrpro.algorithms.reconstruction.DirectReconstruction(kdata)
img_using_ismrmrd_traj = reconstruction(kdata)

Using KTrajectoryRadial2D - Specific trajectory calculator

For some common trajectories, we provide specific trajectory calculators. These calculators often require only a few parameters to be specified, such as the angle between spokes in the radial trajectory. Other parameters will be taken from the ISMRMRD file. This will calculate the trajectory using the radial 2D trajectory calculator.

Note

You can also implement your own trajectory calculator by subclassing KTrajectoryCalculator.

# Read raw data and calculate trajectory using KTrajectoryRadial2D
golden_angle = torch.pi * 0.618034
kdata = mrpro.data.KData.from_file(
    data_folder / 'radial2D_402spokes_golden_angle_with_traj.h5',
    mrpro.data.traj_calculators.KTrajectoryRadial2D(golden_angle),
)

# Reconstruct image
reconstruction = mrpro.algorithms.reconstruction.DirectReconstruction(kdata)
img_using_rad2d_traj = reconstruction(kdata)

Using KTrajectoryPulseq - Trajectory from pulseq sequence file

This will calculate the trajectory from the pulseq sequence file using the PyPulseq trajectory calculator. This method requires the pulseq sequence file that was used to acquire the data. The path to the sequence file is provided as an argument to KTrajectoryPulseq.

# Read raw data and calculate trajectory using KTrajectoryPulseq
seq_path = data_folder / 'radial2D_402spokes_golden_angle.seq'
kdata = mrpro.data.KData.from_file(
    data_folder / 'radial2D_402spokes_golden_angle_with_traj.h5',
    mrpro.data.traj_calculators.KTrajectoryPulseq(seq_path),
)

# Reconstruct image
reconstruction = mrpro.algorithms.reconstruction.DirectReconstruction(kdata)
img_using_pulseq_traj = reconstruction(kdata)

Plot the different reconstructed images

All three images are reconstructed using the same raw data and should look almost identical.

Hide code cell content
import matplotlib.pyplot as plt
import torch


def show_images(*images: torch.Tensor, titles: list[str] | None = None) -> None:
    """Plot images."""
    n_images = len(images)
    _, axes = plt.subplots(1, n_images, squeeze=False, figsize=(n_images * 3, 3))
    for i in range(n_images):
        axes[0][i].imshow(images[i], cmap='gray')
        axes[0][i].axis('off')
        if titles:
            axes[0][i].set_title(titles[i])
    plt.show()
show_images(
    img_using_ismrmrd_traj.rss()[0, 0],
    img_using_rad2d_traj.rss()[0, 0],
    img_using_pulseq_traj.rss()[0, 0],
    titles=['KTrajectoryIsmrmrd', 'KTrajectoryRadial2D', 'KTrajectoryPulseq'],
)
../_images/2d07ced0fe626634858e0ee5ebd04df7d79674c481e21b9f63c155d4ab21bf42.png

Tada! We have successfully reconstructed images using three different trajectory calculators.

Note

Which of these three methods is the best depends on the specific use case: If a trajectory is already stored in the ISMRMRD file, it is the most convenient to use. If a pulseq sequence file is available, the trajectory can be calculated using the PyPulseq trajectory calculator. Otherwise, a trajectory calculator needs to be implemented for the specific trajectory used.