Introduction

Teaching (medical) students about MRI is a balancing act between quantum physics and understandable application. In our medical school, medical students are taught very compressed about the physics of MRI systems at the start of the first semester, and they have a short seminar where a table-top MRI device and a program for generating MRI images are used to show how sequences work and contrasts are generated. A second longer seminar with the same table-top MRI and program is in the fourth year. So far, we have used the software by Hackländer and Mertens [1] for our teaching. It is a Java program that enables students to test different sequences and the influence of various parameters. The software also supports noise addition, k-space manipulations, and motion artifacts. A disadvantage is that students can access it only during class and hence, we saw an urgent need to develop a tool that is remotely accessible. To the best of our knowledge, the only MRI image generator for teaching that is able to easily solve the accessibility problem published in the last decade is by Treceño-Fernández et al. [2]. This system is web-based and therefore, could be made accessible over the internet. It also allows students to test different sequences, set the parameters, add different types of noise, manipulate k-space, and use different B0 inhomogeneities. This tool performs all the calculations exclusively on the server, which leads to high server load and bandwidth usage. Therefore, it is suitable for a class setting using the local network, but probably does not scale well if large groups of students access the web page simultaneously over the internet. In addition to this, Treceño-Fernández et al. focus more on the usage of MRI devices and matched their workflow and user interface to those of real MRIs, while the tool presented here aims to demonstrate differences between sequences and the resulting images. Apart from these two MR image generators, there are a number of simulators published in recent years that run on the local computer [3,4,5,6]. Those simulators are mostly developed for researchers or physics and engineering students. For non-technical students like medical students installing programs or Java, using Matlab, simulators that only run on selected operating systems or complicated interfaces that need in-depth knowledge about Bloch equations or sequences make these simulators inaccessible. We present here a different approach to a web-based image generator that performs all computations on the client to eliminate the scaling problem and has a lean user interface.

MRI generation

For our system, the main goal was to create a teaching tool that is compact, usable across many platforms, intuitive, and with minimal load on the web server.

Requirements

The work for the server should be minimal, which is realized by performing all computations by the client’s device. This requires a system with low computational overhead so that users can run the tool on smartphones or tablets. Programming languages such as HTML, CSS, and JavaScript were used so that the program can be run on any platform with a modern browser. Therefore, the main objective was to make it independent of having a specific operating system, 3rd party software or device. Hence, the following prioritization list has been derived to guide the development of the presented software:

  1. 1.

    low server load

  2. 2.

    remote accessibility

  3. 3.

    cross-platform

  4. 4.

    low resource usage

  5. 5.

    convenient and clear GUI

  6. 6.

    small file sizes

Functions

MRI enables users to create different contrasts between tissues by exploiting different magnetization properties. Therefore, we included multiple sequences, and besides standard hydrogen (¹H), sodium (²³Na) imaging was also included.

Currently, the system supports six basic sequences for ¹H MRI, Spin Echo, Inversion Recovery, and more advanced sequences such as spoiled gradient echo.

The symbols used in the following equations are explained in Table 1

Spin echo [78]

$$\begin{aligned} S \propto pd * e^{\frac{-TE}{T2}} * (1 - e^{\frac{-TR}{T1}}) \end{aligned}$$
(1)

Inversion recovery [910]

$$\begin{aligned} S \propto pd * (1.0 - 2.0 * e^{\frac{-TI}{T1}} + e^{\frac{-TR}{TI}}) * e^{\frac{-TE}{T2}} \end{aligned}$$
(2)

Spoiled gradient echo [1112]

$$\begin{aligned} S \propto pd * \frac{(1-e^{\frac{-TR}{T1}})*sin(FA)}{1-e^{\frac{-TR}{T1}}*cos(FA)} * e^{\frac{-TE}{T2*}} \end{aligned}$$
(3)

Also included are three steady-state sequences. These are common sequences available on commercial MRI scanners and provide contrasts different from the previous three sequences.

Balanced steady-state free precession (True FISP/FIESTA/Balanced FFE) [1314]

$$\begin{aligned} S \propto pd * \frac{(1-e^{\frac{-TR}{T1}})* sin(FA)}{1 - (e^{\frac{-TR}{T1}}-e^{\frac{-TR}{T2}})*cos(FA) - e^{\frac{-TR}{T1}}*e^{\frac{-TR}{T2}} } * e^{\frac{-TE}{T2}} \end{aligned}$$
(4)

Postexcitation refocused steady-state precession (FISP/GRASS, fast MPGR/FFE) [14]

$$\begin{aligned} \begin{aligned} S \propto \;&pd * tan(\frac{FA}{2}) * e^{\frac{-TE}{T2*}} * \left( 1 - (e^{\frac{-TR}{T1}}-cos(FA))*f(TR,T1,T2,FA)\right) \\ f(TR,T1,T2,FA) =&\sqrt{\frac{1-e^{\frac{-2*TR}{T2}}}{ (1-e^{\frac{-TR}{T1}}*cos(FA))^2-e^{\frac{-2*TR}{T2}}*(e^{\frac{-TR}{T1}}-cos(FA))^2}} \end{aligned} \end{aligned}$$
(5)

Preexcitation refocused steady-state precession (PSIF/SSFP/T2-FFE) [14]

$$\begin{aligned} &S \propto \;pd * tan(\frac{FA}{2}) *e^{\frac{-TE}{T2}}\\&*\left( 1-(1-e^{\frac{-TR}{T1}}*cos(FA))* f(TR,T1,T2,FA)\right) \end{aligned}$$
(6)

For 23Na imaging, we implemented the signal equation for 23Na, enabling the creation of conventional 23Na MR images. However, sodium is a quadrupole in its nature and thus, exhibits multi-quantum properties. Under certain conditions, one can observe besides the Single Quantum (SQ) also Triple Quantum (TQ) signal, which could provide a richer tissue sodium characterization. Hence, we implemented CRISTINA [15] so we can generate three 23Na images: conventional, single-, and triple-quantum. The single- and triple-quantum images can be further used to calculate the ratio of triple- to single-quantum signal.

23Na signal [16]

$$\begin{aligned} &S \propto \;(na_{vol}-vol)* mm * (1-e^{\frac{-TR}{T1}}) \\&* (0.6*e^{\frac{-TE}{T2f}} + 0.4*e^{\frac{-TE}{T2s}}) + vol*na_{mm} \\&* (1-e^{\frac{-TR}{T1}})*e^{\frac{-TE}{T2fr}} \end{aligned}$$
(7)

Single quantum spin echo [15]

$$\begin{aligned} S_{sq} \propto \frac{1}{|TEs|} \sum _{TE \in TEs}{mm * ( e^{\frac{-TE+\tau _1}{T2s}} + e^{\frac{-TE+\tau _1}{T2f}} ) * sin(FA) } \end{aligned}$$
(8)

Triple quantum spin echo [15]

$$\begin{aligned} &S_{tq} \propto \frac{1}{|TEs|} \sum _{TE \in TEs} mm * (e^{\frac{-TE}{T2s}} - e^{\frac{-TE}{T2f}}) \\&* (e^{\frac{-\tau _1}{T2s}}-e^{\frac{-\tau _1}{T2f}}) * e^{\frac{-\tau _2}{T2s}} * sin(FA)^5 \end{aligned}$$
(9)

TQ/SQ spin echo

$$\begin{aligned} S \propto \frac{S_{tq}}{S_{sq}} \end{aligned}$$
(10)

For all these functions, the user can change the used parameters. The parameters are mostly the echo time, the repetition time, or the flip angle. For most sequences, we give an estimate of the acquisition time that a real MRI device would need.

Table 1 Explanation for the symbols used in the signal equations

Furthermore, subsampling with different interpolation modes, Gaussian noise, simple k-space manipulation, and 2D or 3D Fourier transform is supported.

For undersampling of the k-space we give a choice of three schemes: Random, density-adapted Pseudo-Random, and Regularly spaced. Random means an arbitrary decision to include or discard a voxel in k-space, yielding non-Cartesian k-space trajectories. The other two schemes retain or discard complete phase-encoding lines in k-space, representing Cartesian trajectories. Regularly spaced means for a 50% sampling fraction \(f_s\) that every second line is measured, for 33% every third. The condition for measuring a line y is shown in Eq. 11. If the condition for measure(y) is true, then the line y is measured; otherwise it will be dropped. The line numbering y starts at 1.

$$\begin{aligned} measure(y) = \left\{ \begin{array}{llr} \frac{\textrm{cei}l\left( y\, \cdot f_{s} \right) }{ f_{s}}-y &{}< 1 &{} f_{s}<0.5 \\ \frac{\textrm{cei}\left( y\,(1-f_{s}) \right) }{ (1-f_{s})}-y &{}\ge 1 &{} f_{s}\ge 0.5 \\ \end{array} \right. \end{aligned}$$
(11)

A commonly used sampling scheme is the density-adapted pseudo-random sampling, which keeps the full k-space center, and the probability to drop a line increases with the distance from the center. This is a common sampling scheme for compressed sensing [17]. We always keep a fraction \(f_{in}\) 10% in the center of the complete k-space. Then a random number is generated at each line and compared to a linearly decreasing threshold. The parameters for this threshold are chosen so that the resulting sampling rate is the selected sampling rate. The calculation for these parameters is shown in Eq. 12. In these equations, \(Dim_y\) is the total number of y lines.

$$\begin{aligned} \begin{array}{ll} b &{}= \left\{ \begin{array}{lr} \frac{f_s - f_{in}}{0.5\,(1-f_{in})} - 1 &{} f_s<0.5\\ 2 - \frac{f_s - f_{in}}{0.5\,(1-f_{in})} &{} f_s\ge 0.5 \end{array}\right. \\ a &{}= \frac{b}{1-f_{in}} \\ \Psi (y) &{}= \left\{ \begin{array}{lr} 2*y/Dim_y &{} y / Dim_y < 0.5\\ 2*(1-y/Dim_y) &{} y / Dim_y \ge 0.5\\ \end{array}\right. \\ measure(y) &{}= r_{random} \le -a\,(\Psi (y)-f_{in})+b \end{array} \end{aligned}$$
(12)

Architecture

The architecture can be viewed on two levels. There is a server-client architecture to deliver the web app to the browser. Here we use static files which can be served by every standard web server. This project is based on the SimpleHttpServer included in Python 3.

The web page uses the Model-View-Controller pattern and offloads the computation to a worker thread. It only connects to the server to load a data set. After that, all computation and data handling is performed within the browser. The view is written in HTML and CSS using the CSS files from the Bootstrap project. Some responsive behavior, e.g. calculating the needed time for a scan, is calculated in JavaScript. The controller uses JavaScript and most of the computation is written in both JavaScript and c/WebASM. An exception is the FFT, where we use the KissFFT project, which is only written in c and then compiled with emscripten to WebASM. This is done to speed up the computations. We purposely did not write everything in c/WebASM so that an interested user can simply open the web developer tools and follow the computation with the built-in debugger. The WebASM version of the image creation process has a faster runtime and is therefore set as the default computation backend.

Data sets

Each data set consists of multiple 3D arrays for the different parameter maps. For 1H MRI that includes: T1, T2, T2*, and proton density. For 23Na, the parameters are T1, T2 fast, T2 slow, sodium density, and extracellular volume fraction. Every array has a size of 256x256x256 voxels and was generated using published head phantoms [18,19,20,21]. The data sets generated using Aubert-Broche et al. [1819] and Holmes et al. [20] are available for 3T and 1T 1H and 3T 23Na MRI and the data set generated from Alfano et al. [21] is 1T and 1.5T 1H MRI. The phantoms we used consisted of segmentation masks for different tissue types. We used these to generate the parameter maps by simply inserting the values for each parameter found in the literature (Tables 2). These maps were then resampled to 256x256x256 voxels.

Table 2 Parameters used for 1.5T 1H, 3T 1H and 3T 23Na images. Parameter names are in analogy to [18]. *: Parameters were not found, approximated with values for fat/muscle

Image generation pipeline

Our generation process (Fig. 1) is quite straightforward. MR images are computed in the image domain using the Eqs. 1 to 10 for every voxel and followed by a Fourier transform to calculate the k-space. For added noise, random numbers, chosen from a Gaussian distribution, are added to each value in the k-space and if undersampling is activated, the k-space is filtered using the selected sampling scheme to remove a configurable percentage of the total lines prior to the inverse Fourier transformation. If the k-space was modified, an inverse Fourier transform is used to compute the final image to be displayed.

Fig. 1
figure 1

Image generation pipeline. The green boxes are part of the front end and the blue ones are in the back end

GUI

The user interface is written using HTML and CSS. The base CSS files are from the bootstrap project (version 5) [27], a toolkit to build web frontends. The dark Gruvbox [28] scheme was chosen for the color theme. When the user opens the web page, they first have to choose a data set. After loading the data set, the input fields for general parameters and sequences become visible (Fig. 2). The link "Dataset source" next to the drop-down box always links to the webpage of the selected data set, where the input files for each data set can be downloaded. An MRI sequence can be selected by clicking on the corresponding tab, which also visualizes the specific parameters for this sequence. The parameters for each sequence are independent, e.g. changing the Echo Time in Inversion Recovery does not change the Echo Time for Spin Echo. Only the selected and visible parameters are used for a sequence, except for the ’23Na TQ/SQ’ sequence, which uses the parameters of the ’23Na SQ’ and ’23Na TQ’ tabs. The field ’Total Measuring Time’ provides an approximation of the time required to conduct the selected MRI experiment.

Fig. 2
figure 2

The GUI after loading a data set. General parameters are stated at the top and sequence specific parameters are found at the bottom

The general parameters are in an accordion menu and can be expanded or collapsed as needed. In the screenshot, the menu "General Parameters" is expanded and the menus for noise and compressed sensing are collapsed. Collapsed menus have a different font color to emphasize that they can be expanded. We chose this to signify that all general parameters are always used for image generation, except for the sequence parameters, only the ones on the currently active and visible tab are used. However, displaying all parameters at once creates an overloaded interface, so the user has the option to collapse them. The button with the label "Start Scan" starts the generation process. The computed images will be displayed below (Fig. 3). The toggle buttons allow the user to select which images should be displayed and to show or hide the respective k-space.

Fig. 3
figure 3

Resulting signal computation for a Spin Echo acquisition based on Eq. 1. The Viewer shows a slice from the transversal, sagittal, and coronal planes and then these three slices in a 3D view. Control panels to manipulate and navigate through the images are found beneath the images

Every image is displayed in a four-panel view. The top left corner contains a transversal, the top right a sagittal, and the bottom left a coronal slice. The bottom right quarter is either the k-space or a 3D view of the current slices, which also allows for rotation of the view.

After generating a second image, the user can now decide to view both of them next to each other (Fig. 4) or only one of them. Figure 4 shows a comparison of two Spin Echo images with different TE values. Additionally, the crosshair has been hidden and the 3D view is replaced with the respective k-spaces.

Fig. 4
figure 4

Generation of a second Spin Echo image. On the left-hand side is the previous Spin Echo image from Fig. 3 and on the right side the new Spin Echo image is shown. The crosshair has been turned off and the 3D view replaced with the k-space

The user can interact with the other sections of the image by holding the mouse button and moving it, which changes the center and width of the window. The slice can be changed with the mouse wheel. Both the windowing and the slice can also be selected using the input fields below the image. When a 23Na is created, the selection fields for the windowing are replaced by a color bar. Slice selection for the image and the k-space is partly synchronized. Scrolling through one image also scrolls through the other visible images, enabling users to compare images with different acquisition parameters and sequences. Slice selection using the input boxes below the image is not synchronized. This allows a user to set every image to a different slice. In that case, the scrolling is still synchronized, but the offset between the slices is kept until one image is at the first or last slice.

To generate an image with a lower resolution, the value of the scale field has to be changed. The interpolation mode then decides how to calculate the voxel value. Possible options are to use the nearest neighbor or to average over all voxels in the data set that would be within the virtual image voxel.

Results

We will focus on the impact of changing the general parameters, resolution, interpolation mode, 3D vs. 2D FFT, computational subsystem, and noise (Table 3). For all parameters, the JavaScript version was much slower than WebASM. Chrome was always slower than Firefox when using WebASM, but Chrome was faster most of the time when using the JavaScript version. Generating an image using only the nearest point of the data set to the center of a voxel is faster than averaging over all data points inside the voxel. Reducing the size of the generated image also reduces the computation time, since the Fourier transformations are quicker and they take up a big share of the total computation time. When noise is added to the k-space, an additional inverse Fourier transform is required to obtain the noisy image, which, as expected, increases the running time.

Table 3 Runtimes for several parameter combinations using a Spin Echo sequence (TE: 23, TR: 666). All parameter combinations are computed with the slow JavaScript and the faster WebASM version. The runtimes are averaged over 10 runs, on a PC with Intel i5-6500 CPU and 64GB RAM. Maximum RAM used by the Browsers: Firefox 1.8GB, Chrome 1.9GB

Spin Echo and Inversion Recovery images generated with the here proposed software are shown in Fig. 5. The first four rows show generated images using Spin Echo and different echo time, (\(TE_1=0.1ms\),\(TE_2=13ms\),\(TE_3=42ms\),\(TE_4=121ms\)). Furthermore, two Inversion Recovery images are shown with different inversion times chosen to suppress White Matter (\(TI_1=600ms\)) and Grey Matter (\(TI_2=993ms\)).

Fig. 5
figure 5

Generated images using the Spin Echo sequence (Eq. 1) with different Echo Times and Inversion Recovery sequence (Eq. 2) with different inversion times. In all rows, the shown slices are the middle slice in the transversal, sagittal, and coronal planes

The steady-state sequences are shown in Fig. 6. Similar to the previous figure, different parameters are used in each row and the same three slices of the head are shown.

Fig. 6
figure 6

Images computed using the steady-state sequences balanced SSFP (Eq. 4), FISP (Eq. 5), and PSIF (Eq. 6)

Figure 7 shows the Spin Echo sodium sequences in addition to single and triple quantum imaging. These images are generated with a reduced resolution to better resemble state-of-the-art for sodium imaging in reality. The Spin Echo images are downsampled to an isotropic voxel size of 4mm and the single/triple quantum images have a voxel size of 16mm.

Fig. 7
figure 7

Images were computed using the equations for the sodium sequences. The top three rows show 23Na Spin Echo (Eq. 7), then follows a single quantum (Eq. 8) and a triple quantum (Eq. 9) image. The voxel size and spacing for the single/triple quantum images is 16mm

Discussion

In summary, we have presented a web-based image generator designed for teaching. The software allows the generation of signals based on different sequences and the demonstration of the influence of the parameters. It supports a vast amount of sequences ranging from standard proton Spin Echo to more advanced sodium sequences. Further, the system contains the options to add noise, change image resolution, and k-space undersampling with different strategies. Secondly, a user-friendly interface was developed that eases usage. Additionally, the software can run on a wide range of devices, which is attributed to the fact, that the software was developed as a web-based application. Lastly, the server management and costs are reduced since we have only static files. No computation is necessary on the server, and static files can be distributed to many clients without much effort. Deploying to a new server is also simple, just copy the "wwwroot" folder from the GitHub repository [29], this contains all the required source and data files.

Our tool started as a small piece of software, but with added functions, it increased in size and computational cost. While still able to be used on smartphones, a user has to wait for some time until the computation process is finished. One solution to reduce computational cost would be to detect mobile devices like a smartphone and then provide a reduced version of the web page, e.g. only allowing nearest-neighbor interpolation and 2D Fourier transformation. Another solution, which we implemented already, is to code the computationally intense algorithms in c and then compile them to WebASM. This makes the computation process less transparent because interested users would not be able to simply open the web debugger (which can be accessed in most major browsers by pressing F12) and look at how the program runs inside their browser. On the other hand, we see that the WebASM version only takes  50% of the time required by the JS version to calculate an image. This will allow a user to choose between the slow, but debuggable, JavaScript and the fast, oblique WebASM version.

Future work will focus on including parallel imaging and compressed sensing. Both are implemented in modern MRI devices and are quite interesting.

The added noise and image artifacts are quite basic. So far, the user can only select Gaussian noise. A possible artifact we could add without much hassle is B0 homogeneity by extending the image creation process with the inclusion of a static homogeneity map. The movement of the patient would be somewhat more difficult. To include a single and fast movement of the complete patient, the interpolation grid could be shifted and rotated during the computation. This would require computing the images and k-spaces twice, and then merging these k-spaces so that the points captured before and after the motion are from the corresponding k-space. While this is not a perfect representation of patient movement, it should be a usable approximation and starting point for more complex movements. The flexible interpolation grid required for the proposed patient motion artifacts could also be used for other purposes, such as changing the orientation of the slices. Setting the slice orientation could be done by simply changing values for the rotation in several input boxes. But we think this would not be intuitive and a better approach is a 3D view, similar to what Treceño-Fernández et al. implemented.

Other tools focus on having a GUI that resembles a real MRI machine. However, we focused on convenience in regard to usage and accessibility, which was the reason to neglect the implementation of a scanner related interface. The workflow for acquiring images on a real MRI is beyond the scope of this software.

In conclusion, we have presented a web-based image generator for a wide range of MR sequences that is scalable, cross-platform, and freely available.