From 37b05753e42b725f5879da4397669db327aa4971 Mon Sep 17 00:00:00 2001 From: Ariel Rokem Date: Sat, 10 Apr 2021 10:24:06 -0700 Subject: [PATCH 1/5] A few suggestions on the models chapter. --- docs/head-motion/models.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/head-motion/models.md b/docs/head-motion/models.md index d17347b..261aeaf 100644 --- a/docs/head-motion/models.md +++ b/docs/head-motion/models.md @@ -13,13 +13,13 @@ kernelspec: # Diffusion modeling The proposed method requires inferring a motion-less, reference DW map for a given diffusion orientation for which we want to estimate the misalignment. -Inference of the reference map is achieved by first fitting some diffusion model (which we will draw from [DIPY](https://dipy.org)) using all data, except the particular DW map that is to be aligned. +Inference of the reference map is achieved by first fitting some diffusion model (which we will draw from [DIPY](https://dipy.org)) using all data, except the particular DW map that is to be aligned. We call this scheme "leave one gradient out" or "logo". All models are required to offer the same API (application programmer interface): -1. The initialization takes a gradient table as first argument, and then arbitrary parameters as keyword arguments. -2. A `fit(data)` method, which only requires a positional argument `data`. -3. A `predict(gradient)` method, which only requires a `gradient` entry (b-vector and b-value). +1. The initialization takes a DIPY `GradientTable` as the first argument, and then arbitrary parameters as keyword arguments. +2. A `fit(data)` method, which only requires a positional argument `data`, a 4D array with DWI data. +3. A `predict(gradient_table)` method, which only requires a `GradientTable` as input. This method produces a prediction of the signal for every voxel in every direction represented in the input `gradient_table`. ```{code-cell} python :tags: [hide-cell] @@ -50,34 +50,30 @@ class TrivialB0Model: and to read (see https://www.youtube.com/watch?v=3MNVP9-hglc). """ - __slots__ = ("_S0",) + __slots__ = ("_gtab", "_model_params") def __init__(self, gtab, S0=None, **kwargs): """Implement object initialization.""" - if S0 is None: - raise ValueError("S0 must be provided") + self._gtab - self._S0 = S0 - - def fit(self, *args, **kwargs): + def fit(self, data, **kwargs): """Do nothing.""" + self._model_params = np.mean(np.data[..., self.gtab.b0s_mask], -1) - def predict(self, gradient, **kwargs): + def predict(self, gtab, **kwargs): """Return the *b=0* map.""" - return self._S0 + return self._model_params ``` - The model can easily be initialized as follows (assuming we still have our dataset loaded): ```{code-cell} python model = TrivialB0Model( dmri_dataset.gradients, - S0=dmri_dataset.bzero ) ``` -Then, at each iteration of our estimation strategy, we will fit this model (which does nothing) to the diffusion weighted data after holding one particular direction (`data_test`) out: +Then, at each iteration of our estimation strategy, we will fit this model to the data, after holding one particular direction (`data_test`) out, using the `logo_split` method of the dataset. In every iteration, this finds the b=0 volumes in the data and averages their values in every voxel: ```{code-cell} python data_train, data_test = dmri_dataset.logo_split(10) @@ -183,7 +179,7 @@ data_train, data_test = dmri_dataset.logo_split(88, with_b0=True) ``` ### The model factory -To permit flexibly select models, the `eddymotion` package offers a `ModelFactory` that implements the *facade design pattern*. +To permit flexibly in selecting models, the `eddymotion` package offers a `ModelFactory` that implements the *facade design pattern*. This means that `ModelFactory` makes it easier for the user to switch between models: ```{code-cell} python From 0dd051228bc8128576f5c5064cce6e82b9ee1832 Mon Sep 17 00:00:00 2001 From: Ariel Rokem Date: Sat, 10 Apr 2021 10:32:41 -0700 Subject: [PATCH 2/5] Reverts changes to the b0 model. --- docs/head-motion/models.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/head-motion/models.md b/docs/head-motion/models.md index 261aeaf..77f28fe 100644 --- a/docs/head-motion/models.md +++ b/docs/head-motion/models.md @@ -41,28 +41,34 @@ This model will allow to easily test the overall integration of the different co Also, this model will allow a very straightforward implementation of registration to the *b=0* reference, which is commonly used to initialize the head-motion estimation parameters. ```{code-cell} python + class TrivialB0Model: """ A trivial model that returns a *b=0* map always. + Implements the interface of :obj:`dipy.reconst.base.ReconstModel`. Instead of inheriting from the abstract base, this implementation follows type adaptation principles, as it is easier to maintain and to read (see https://www.youtube.com/watch?v=3MNVP9-hglc). + """ - __slots__ = ("_gtab", "_model_params") + __slots__ = ("_S0",) def __init__(self, gtab, S0=None, **kwargs): """Implement object initialization.""" - self._gtab + if S0 is None: + raise ValueError("S0 must be provided") - def fit(self, data, **kwargs): + self._S0 = S0 + + def fit(self, *args, **kwargs): """Do nothing.""" - self._model_params = np.mean(np.data[..., self.gtab.b0s_mask], -1) - def predict(self, gtab, **kwargs): + def predict(self, gradient, **kwargs): """Return the *b=0* map.""" - return self._model_params + return self._S0 + ``` From ff572c788059149c1dd0ad8f17420d351f2c387e Mon Sep 17 00:00:00 2001 From: Ariel Rokem Date: Sat, 10 Apr 2021 11:03:04 -0700 Subject: [PATCH 3/5] Update docs/head-motion/models.md Co-authored-by: Oscar Esteban --- docs/head-motion/models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/head-motion/models.md b/docs/head-motion/models.md index 77f28fe..ec3089c 100644 --- a/docs/head-motion/models.md +++ b/docs/head-motion/models.md @@ -185,7 +185,7 @@ data_train, data_test = dmri_dataset.logo_split(88, with_b0=True) ``` ### The model factory -To permit flexibly in selecting models, the `eddymotion` package offers a `ModelFactory` that implements the *facade design pattern*. +To permit flexibility in selecting models, the `eddymotion` package offers a `ModelFactory` that implements the *facade design pattern*. This means that `ModelFactory` makes it easier for the user to switch between models: ```{code-cell} python From a9a831e55afaaafdfdf496c7ea2db38c5db1482d Mon Sep 17 00:00:00 2001 From: Ariel Rokem Date: Sat, 10 Apr 2021 11:03:19 -0700 Subject: [PATCH 4/5] Update docs/head-motion/models.md Co-authored-by: Oscar Esteban --- docs/head-motion/models.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/head-motion/models.md b/docs/head-motion/models.md index ec3089c..bd46595 100644 --- a/docs/head-motion/models.md +++ b/docs/head-motion/models.md @@ -19,7 +19,8 @@ All models are required to offer the same API (application programmer interface) 1. The initialization takes a DIPY `GradientTable` as the first argument, and then arbitrary parameters as keyword arguments. 2. A `fit(data)` method, which only requires a positional argument `data`, a 4D array with DWI data. -3. A `predict(gradient_table)` method, which only requires a `GradientTable` as input. This method produces a prediction of the signal for every voxel in every direction represented in the input `gradient_table`. +3. A `predict(gradient_table)` method, which only requires a `GradientTable` as input. + This method produces a prediction of the signal for every voxel in every direction represented in the input `gradient_table`. ```{code-cell} python :tags: [hide-cell] From 6ec76ada874d673140432e82cc927aead58514fd Mon Sep 17 00:00:00 2001 From: Ariel Rokem Date: Sat, 10 Apr 2021 11:03:30 -0700 Subject: [PATCH 5/5] Update docs/head-motion/models.md Co-authored-by: Oscar Esteban --- docs/head-motion/models.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/head-motion/models.md b/docs/head-motion/models.md index bd46595..9471470 100644 --- a/docs/head-motion/models.md +++ b/docs/head-motion/models.md @@ -13,7 +13,8 @@ kernelspec: # Diffusion modeling The proposed method requires inferring a motion-less, reference DW map for a given diffusion orientation for which we want to estimate the misalignment. -Inference of the reference map is achieved by first fitting some diffusion model (which we will draw from [DIPY](https://dipy.org)) using all data, except the particular DW map that is to be aligned. We call this scheme "leave one gradient out" or "logo". +Inference of the reference map is achieved by first fitting some diffusion model (which we will draw from [DIPY](https://dipy.org)) using all data, except the particular DW map that is to be aligned. +We call this scheme "leave one gradient out" or "logo". All models are required to offer the same API (application programmer interface):