.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "generated\examples\tutorials\plot_multislice.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_generated_examples_tutorials_plot_multislice.py: =============================================== Multi-slice 2D registration =============================================== By default mdreg performs 3D coregistration on 3D series, and 2D coregistration on 2D series. In case the 3D series encodes a collection of 2D slices with gaps in between (multi-slice data), this may not be appropriate. This examples shows how mdreg can be used to perform 2D coregistration slice-by-slice on a 3D series by setting the keyword argument force_2d=True. .. GENERATED FROM PYTHON SOURCE LINES 15-17 Setup ----- .. GENERATED FROM PYTHON SOURCE LINES 17-20 .. code-block:: Python import numpy as np import mdreg .. GENERATED FROM PYTHON SOURCE LINES 21-22 Fetch the multi-slice MOLLI dataset .. GENERATED FROM PYTHON SOURCE LINES 22-29 .. code-block:: Python data = mdreg.fetch('MOLLI') # Get the relevant variables (3D data) array = data['array'] TI = np.array(data['TI'])/1000 .. GENERATED FROM PYTHON SOURCE LINES 30-32 Perform slice-by-slice motion correction ---------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 32-46 .. code-block:: Python # Define the signal model molli = { 'func': mdreg.fit_abs_exp_recovery_2p, 'TI': np.array(data['TI'])/1000, } # Perform motion correction coreg, fit, defo, pars = mdreg.fit( array, fit_image=molli, force_2d=True, maxit=1, ) .. GENERATED FROM PYTHON SOURCE LINES 47-49 Since coregistration is performed in 2D, the deformation field only has two components: .. GENERATED FROM PYTHON SOURCE LINES 49-51 .. code-block:: Python print(f'The deformation field has {defo.shape[-1]} components.') .. rst-class:: sphx-glr-script-out .. code-block:: none The deformation field has 2 components. .. GENERATED FROM PYTHON SOURCE LINES 52-53 Visualise the results .. GENERATED FROM PYTHON SOURCE LINES 53-55 .. code-block:: Python anim = mdreg.plot.series(array, fit, coreg, vmin=0, vmax=1e4) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /generated/examples/tutorials/images/sphx_glr_plot_multislice_001.png :alt: Series Type: Original Data , Slice 1, Slice 2 :srcset: /generated/examples/tutorials/images/sphx_glr_plot_multislice_001.png :class: sphx-glr-multi-img * .. image-sg:: /generated/examples/tutorials/images/sphx_glr_plot_multislice_002.png :alt: Series Type: Model Fit , Slice 1, Slice 2 :srcset: /generated/examples/tutorials/images/sphx_glr_plot_multislice_002.png :class: sphx-glr-multi-img * .. image-sg:: /generated/examples/tutorials/images/sphx_glr_plot_multislice_003.png :alt: Series Type: Coregistered , Slice 1, Slice 2 :srcset: /generated/examples/tutorials/images/sphx_glr_plot_multislice_003.png :class: sphx-glr-multi-img .. GENERATED FROM PYTHON SOURCE LINES 56-67 Different options per slice --------------------------- It is not uncommon that each slice in a multislice sequence has different imaging parameters. For instance in a MOLLI sequence such as used in this example, it is often the case that each slice has its own set of TI values. The situation can be accomodated in `~mdreg.fit` by assigning a list of dictionaries to the *fit_image* argument - one for each slice. We illustrate that here assuming that the TI's for each slice are offset by 100 ms relative to the previous slice: .. GENERATED FROM PYTHON SOURCE LINES 67-78 .. code-block:: Python molli = [ { 'func': mdreg.fit_abs_exp_recovery_2p, 'TI': TI + 0.1 * z, } for z in range(array.shape[2]) ] # Other than that, the function call to `mdreg.fit()` is the same as before. .. GENERATED FROM PYTHON SOURCE LINES 79-82 Other coregistration packages ----------------------------- This works the same when using ants or elastix for coregistration: .. GENERATED FROM PYTHON SOURCE LINES 82-92 .. code-block:: Python # Perform motion correction coreg, fit, transfo, pars = mdreg.fit( array, fit_image=molli, fit_coreg={'package': 'ants'}, force_2d=True, maxit=1, ) .. rst-class:: sphx-glr-script-out .. code-block:: none invalid value encountered in cast .. GENERATED FROM PYTHON SOURCE LINES 93-95 The difference with skimage is that the transformations returned are now a 2D array with one transformation at each time and each slice: .. GENERATED FROM PYTHON SOURCE LINES 95-97 .. code-block:: Python print(f'2D transformation shape: {transfo.shape}') .. rst-class:: sphx-glr-script-out .. code-block:: none 2D transformation shape: (2, 8) .. GENERATED FROM PYTHON SOURCE LINES 98-100 Compare this to 3D registration, where one 3D transformation for each time point is returned: .. GENERATED FROM PYTHON SOURCE LINES 100-111 .. code-block:: Python coreg, fit, transfo, pars = mdreg.fit( array, fit_image=molli[0], fit_coreg={'package': 'elastix'}, maxit=1, ) print(f'3D transformation shape: {transfo.shape}') .. rst-class:: sphx-glr-script-out .. code-block:: none Elastix coregistration failed. Returning unregistered image. To learn more about the error, set log=True. 3D transformation shape: (8,) .. GENERATED FROM PYTHON SOURCE LINES 112-119 Slice by slice with pixel models -------------------------------- If the signal model fit is defined with a custom model via the *fit_pixels* argument, the slice-by-slice operation works the same: set the *force_2d* keyword to True, and - if each slice has different parameter settings - supply the *fit_pixels* argument as a list of dictionaries. .. GENERATED FROM PYTHON SOURCE LINES 119-137 .. code-block:: Python molli = [ { 'model': mdreg.abs_exp_recovery_2p, 'xdata': TI + 0.1 * z, 'func_init': mdreg.abs_exp_recovery_2p_init, 'p0': [1, 1], } for z in range(array.shape[2]) ] coreg, fit, transfo, pars = mdreg.fit( array, fit_pixels=molli, force_2d=True, maxit=1, ) .. rst-class:: sphx-glr-script-out .. code-block:: none Covariance of the parameters could not be estimated overflow encountered in exp overflow encountered in multiply .. rst-class:: sphx-glr-timing **Total running time of the script:** (21 minutes 18.343 seconds) .. _sphx_glr_download_generated_examples_tutorials_plot_multislice.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_multislice.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_multislice.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_multislice.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_