diff --git a/docs/notebooks/pet_motion_estimation.ipynb b/docs/notebooks/pet_motion_estimation.ipynb index f695be6d1..5b46d0b0d 100644 --- a/docs/notebooks/pet_motion_estimation.ipynb +++ b/docs/notebooks/pet_motion_estimation.ipynb @@ -1,11 +1,31 @@ { "cells": [ { - "cell_type": "code", - "execution_count": 1, - "id": "4111cc1b-5123-407a-8ec6-56d65bc94bc4", "metadata": {}, + "cell_type": "markdown", + "source": [ + "# Positron emission tomography (PET) data realignment example\n", + "\n", + "This example shows how to estimate the head motion of a PET dataset using\n", + "`NiFreeze`.\n", + "\n", + "The notebook uses the `sub-02` dataset that was generated synthetically from\n", + "a real PET dataset by adding random motion. The dataset can be installed\n", + "from [GIN G-node](https://gin.g-node.org/nipreps-data/tests-nifreeze):\n", + "\n", + "```\n", + "$ datalad install -g https://gin.g-node.org/nipreps-data/tests-nifreeze.git\n", + "```\n", + "\n", + "after which the environment variable `TEST_DATA_HOME` will need to be set to point to the corresponding folder.\n" + ], + "id": "e0f292c6b783bafa" + }, + { + "metadata": {}, + "cell_type": "code", "outputs": [], + "execution_count": 1, "source": [ "from os import getenv\n", "from pathlib import Path\n", @@ -30,7 +50,8 @@ ")\n", "\n", "pet_dataset = PET.load(pet_file, json_file)" - ] + ], + "id": "6d67b411d3c9330d" }, { "cell_type": "code", @@ -53,6 +74,17 @@ "pet_dataset" ] }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "## Model fitting and motion correction\n", + "\n", + "The relevant structure to model PET data is `nifreeze.model.PETModel`. We\n", + "instantiate it by providing it with the loaded PET dataset." + ], + "id": "886c5ca9bd9eb3e4" + }, { "cell_type": "code", "execution_count": 4, @@ -421,6 +453,18 @@ "model.fit_predict(None)" ] }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "Let's now ask the model for a prediction at the `midframe[2]` time point. By\n", + "calling `model.fit_predict` the model is fitted using all the available data,\n", + "and a prediction is requested on the time provided as the argument. The\n", + "B-Spline PET model employs uses a B-Spline-based interpolation method to\n", + "estimate the data for the requested frame." + ], + "id": "cbd738998dd6ed1f" + }, { "cell_type": "code", "execution_count": 7, @@ -432,6 +476,15 @@ "predicted = model.fit_predict(pet_dataset.midframe[index])" ] }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "We now save the uncorrected and corrected data so that we can visualize the\n", + "difference." + ], + "id": "17f3d61720ac0959" + }, { "cell_type": "code", "execution_count": 8, @@ -452,6 +505,15 @@ "nifti_img_after.to_filename(output_path_after)" ] }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "Let's now visualize a number of axial, sagittal and coronal slices of the\n", + "uncorrected and corrected data." + ], + "id": "7126dd0b08f3d70e" + }, { "cell_type": "code", "execution_count": 10, @@ -2242,10 +2304,21 @@ ] }, { - "cell_type": "code", - "execution_count": 13, - "id": "78edfed2-8200-48be-9f58-8fb910fac299", "metadata": {}, + "cell_type": "markdown", + "source": [ + "## Motion estimation\n", + "\n", + "We now want to have an estimate of the motion that the model corrects. We will\n", + "need to instantiate the `nifreeze.estimator.PETMotionEstimator`, which will\n", + "take an instance of the model. We will call `run` to get the parameters of the\n", + "affine transform estimation." + ], + "id": "44d029b581d72b55" + }, + { + "metadata": {}, + "cell_type": "code", "outputs": [ { "name": "stderr", @@ -2255,6 +2328,7 @@ ] } ], + "execution_count": 13, "source": [ "from nifreeze.estimator import PETMotionEstimator\n", "\n", @@ -2265,7 +2339,8 @@ " pet_dataset,\n", " omp_nthreads=4,\n", ")" - ] + ], + "id": "af6ca1ccbce1e579" }, { "cell_type": "code", @@ -2427,6 +2502,15 @@ "affines" ] }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "Let's now visualize the estimated motion: we will plot the translation and\n", + "rotation components in the affine transform for each axis." + ], + "id": "79a4b84912aed9f9" + }, { "metadata": {}, "cell_type": "code", @@ -2537,14 +2621,6 @@ "\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "14308ff4-d5b1-4270-aca2-0d7e9ccef27f", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": {