This is a short tutorial of how to use the Gadgetron image reconstruction framework. We will be working with version 3.11.0-c2092576.
Here is a video walkthroug of the tutorial:
- Some basic knowledge of MRI reconstruction
- Docker if you are working on a Linux computer or Docker Toolbox if you are on Windows or Mac.
- An HDF5 viewer. Here we use HDFView but you can also read the images into Matlab or Python for display.
In case you want to dig straight in:
$ docker run -t --name gt1 --detach --volume $(pwd):/opt/data gadgetron/ubuntu_1404_cuda75
This will (first download and then) launch the Gadgetron in a Docker container. It will also mount your current folder as a data folder inside the container. To enter the container:
$ docker exec -ti gt1 /bin/bash
Inside the container generate some data:
$ cd /opt/data $ ismrmrd_generate_cartesian_shepp_logan
Send the data for reconstruction in the Gadgetron:
$ gadgetron_ismrmrd_client -f testdata.h5 -c default.xml -o out.h5
out.h5 file with an application such as HDFView and look at the image.
For more details read the complete tutorial below.
Running the Gadgetron using Docker
If you would like to compile and install the Gadgetron and dependencies on your own system, please consult the Gadgetron Wiki. We will use Docker images to simplify this procedure.
The easiest way to get the Gadgetron installed is by using one of our pre-built and tested Docker images, which are available on Docker Hub. The most complete image (in terms of compiled features) is
gadgetron/ubuntu_1404_cuda75 which includes all GPU dependent libraries. If you don’t have a GPU on your machine or if you are running the Docker container on a Windows or Mac computer (where your GPU would not be accesible), you can grab the
gadgetron/ubuntu_1404_no_cuda. For the purposes of this tutorial, either will do.
$ docker pull gadgetron/ubuntu_1404_cuda75
If this is the first time you pull this image, it could take a few minutes depending on network bandwidth and other issues. Once the pull is complete, you should be able to type:
$ docker images
And see the available images on your machine:
To start a container using this image, we will use the command:
For a complete list of all the
docker run options, please refer to the Docker documentation. The
-t attaches a pseudo TTY to the container to enable us to have command line access (see later),
--detach puts the container in the background,
--name gives the container a convenient name (we will use that later), and
--volume $(pwd):/opt/data maps the current directory (
pwd) into a folder called
/opt/data inside the container. If you execute that command from a folder where you have to data to process, you will have access to that data inside the container. If you would like to map some other folder than your current directory, you would type:
After starting the container, you can verify that it is running:
you should see that you have the Gadgetron container running:
You are now ready to run Gadgetron reconstructions.
One note regarding access to GPU inside the container. At the moment this only works on Linux machines. NVIDIA provides a drop-in replacement for the
docker command called
nvidia-docker, which you can find here. We also provide a script in the Gadgetron code, which performs a similar function. These tools will expose the GPU inside the container and allow you to do GPU reconstructions. For more details, please consult the Wiki.
Running the Hello World example
First step to working with the running Gadgetron is to get a command line (shell) inside the container:
$ docker exec -ti gt1 bash
-ti options give us an interactive terminal,
gt1 refers to the name of the container that we used above and
bash is the command to execute inside the container.
Once you are inside the container, you can navigate to the data folder that we mapped:
$ cd /opt/data
If you had any data files in your current directory when you started the container, you should see them here by typing
ls. We will not assume that you have any data yet, so we will use the
ismrmrd_generate_cartesian_shepp_logan application from the ISMRMRD package to generate a dataset.
For more options for this application you can type
ismrmrd_generate_cartesian_shepp_logan -h. The application should generate a
testdata.h5 file in your current folder, which will contain a simulated dataset in ISMRMRD format
To reconstruct the test data type:
-f option is the input file,
-o is the output file and
-c indicates the Gadgetron reconstruction that should be run. The
gadgetron_ismrmrd_client has a few options, which you can list with
gadgetron_ismrmrd_client -h. As indicated by the name, this program is a client, which connects (via a TCP/IP connection) to a Gadgetron server. This server is already running in the container and receiving connections on port
9002, which is the default port for the Gadgetron. If you want to connect to a Gadgetron running on a different port, use the
After running the reconstruction, you can open up the
out.h5 file in HDFView. When you run a new reconstruction, the default behavior of the
gadgetron_ismrmrd_client is to append another group to the HDF5 file with the current date and time. If you keep running reconstructions they will be appended to the time file and organized by time. If you navigate to the
image_0/data variable under the last recon group, you can right-click and select “Open As”. This will bring up a dialog window where you can select “Image” and specify the ordering of the dimensions to display. If you select “Height” to be “dim 3”, “Width” to be “dim 4” and “Depth” to be “dim 0”, you should be able to view the resulting image as illustrated below:
Modifying a reconstruction
Next step is to modify the reconstruction program that we just used. We will add a raw data filter.
Before we get to that, let’s take a closer look at the XML files that define reconstruction programs. You will find the available configurations in
/usr/local/share/gadgetron/config. If you open up the
default.xml program that we used above, you will see that it consists of
gadget definitions. The readers and writers represent the datatypes that this reconstruction program will be able to read (receive) from and write (return) to the client. The default chain is able to read ISMRMRD acquisitions and write MRI images:
The Gadgets represent signal processing modules. The data passes from one module to the next. Each of the
gadget definitions consist of a name, a shared library (DLL) that this Gadget is found in, and the class name of the Gadget. For instance
adds a Gadget with a class name of
RemoveROOversamplingGadget from the shared library
gadgetron_mricore. On Linux, this library would be called
libgadgetron_mricore.so. You can find more details about this Gadget with the command
$ gadgetron_info gadgetron_mricore RemoveROOversamplingGadget
gadgetron_info can give you information about the computer running the Gadgetron and which version of the software you are running. If you ever need to report a problem or a bug, please include the output of
default.xml chain contains the following Gadgets:
RemoveROOversamplingGadget: Removes the readout oversampling
AcquisitionAccumulateTriggerGadget: Collects lines of k-space until a certain trigger condition is encountered, i.e., when there is enough data to reconstruct an image.
BucketToBufferGadget: Inserts the collected data into a buffer more suitable for recon processing.
SimpleReconGadget: Performs a simple FFT reconstruction.
ImageArraySplitGadget: The previous Gadget may return an array of images and this Gadget splits them into individual images.
ExtractGadget: Extracts the magnitude of the complex images.
ImageFinishGadget: Returns the image to the client.
Our task of inserting a raw data filter is now as simple as inserting a Gadget in the beginning of the chain. Most of the Gadgets in the Gadgetron are written in C++ but they can also be written in scripting languages (Python or Matlab). To illustrate this, we will write a Python Gadget.
Simply open up a text editor and start editing a file called
vim are available in the container. Enter the following code:
Now we need to add this Gadget to the
default.xml chain. It is recommended that you copy the
default.xml chain to a new file first:
$ cd /usr/local/share/gadgetron/config $ cp default.xml default_filter.xml
Now edit the
default_filter.xml file and add the following
gadget definition before the
Save the file and now run your new reconstruction on the test data that we created above:
$ gadgetron_ismrmrd_client -f testdata.h5 -o out.h5 -c default_filter.xml
The figure below illustrates the result from the Hello World example side by side with the result from the new chain. It should be clear that the new result is filtered.
Converting and Reconstructing real data
The examples above used simulated data. You would of course want to use real data. Since the Gadgetron supports the ISMRMRD format for MRI data, you can use the Gadgetron as long as you can convert your data to ISMRMRD format. Please look at the ISMRMRD Github for a converter for your preferred vendor. The Docker image comes with some converters already installed. In this example, we will convert a Siemens raw data file to ISMRMRD format and reconstruct it.
In this example we will use the
meas_MID03485_FID51095_se.dat file from the ISMRMRD paper raw dataset which can be downloaded from http://dx.doi.org/10.5281/zenodo.33166. Download the file and place it in the folder that is mounted inside the Docker container.
The example dataset is a more complicated case. The
meas_MID03485_FID51095_se.dat file actually contains two measurements: 1) a noise calibration and 2) the actual measurement data. The noise data can be used for noise prewhitening. To convert the file type:
$ siemens_to_ismrmrd -f meas_MID03485_FID51095_se.dat -z 1 -o noise.h5 $ siemens_to_ismrmrd -f meas_MID03485_FID51095_se.dat -z 2 -o data.h5
This puts the first measurement (
-z 1) into a file called
noise.h5 and the measurement data into a file called
data.h5. We can run these through the Gadgetron one after another. First the noise:
$ gadgetron_ismrmrd_client -f noise.h5 -c default_measurement_dependencies.xml
This will not actually produce any images, it will simply process the noise data and store it in the Gadgetron. Then we run the actual scan:
$ gadgetron_ismrmrd_client -f data.h5 -c Generic_Cartesian_Grappa_SNR.xml
This will produce a new group in the
out.h5 file. If we look at the first image series
image_0 in that, we should see an image:
You will notice that this reconstruction produce other image series as well. How many depends on whether this scan uses parallel imaging or not. The
image_300 series is an image scaled to units of SNR and the
image_1000 series is a plot of the noise standard deviation in each channel. This is a very useful plot for coil QA:
This concludes the brief tutorial of the Gadgetron. You should explore the
/usr/local/share/gadgetron/config folder where you will find many different reconstruction programs. You can also try to implement the raw filter Gadget from above in C++. A good place to start would be the
AcquisitionPassthroughGadget, which could easily be modified to filter the data rather than let it pass straight through.