# Need help understanding codes from sitk notebook

**URL:** <https://discourse.itk.org/t/need-help-understanding-codes-from-sitk-notebook/7228>\
**Category:** Beginner Questions\
**Tags:** simpleitk, registration, python\
**Created:** [September 19, 2024, 1:09pm UTC](https://discourse.itk.org/t/need-help-understanding-codes-from-sitk-notebook/7228 "2024-09-19T13:09:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Learner](https://discourse.itk.org/letter_avatar_proxy/v4/letter/l/b782af/32.png) [@Learner](https://discourse.itk.org/u/Learner)\
**Post date:** [September 19, 2024, 1:09pm UTC](https://discourse.itk.org/t/need-help-understanding-codes-from-sitk-notebook/7228/1 "2024-09-19T13:09:10Z")

</div>

I need help understanding some codes lines from sitk notebook (63\_Registration\_Initialization), link [here](https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks/blob/master/Python/63_Registration_Initialization.ipynb).

I will (1) show the codes that I am using, (2) then ask my specific questions. I have so many questions (I apologise in advance!), and that’s mainly because I don’t want to blindly apply the codes without understanding them. I have changed some parameters from the original notebook, but the final registration is off by few slices/frames.

1. The codes that I am using for registration:

```auto
def multires_registration(fixed_image, moving_image, initial_transform):
    registration_method = sitk.ImageRegistrationMethod()
    registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
    registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
    registration_method.SetMetricSamplingPercentage(0.5)
    registration_method.SetInterpolator(sitk.sitkLinear)
    registration_method.SetOptimizerAsGradientDescent(
        learningRate=1.0,
        numberOfIterations=100,
        estimateLearningRate=registration_method.Once,
    )
    registration_method.SetOptimizerScalesFromPhysicalShift()
    registration_method.SetInitialTransform(initial_transform, inPlace=False)
    registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[1, 1, 1])
    registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[1, 1, 1])
    registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

    final_transform = registration_method.Execute(fixed_image, moving_image)
    print(f"Final metric value: {registration_method.GetMetricValue()}")
    print(
        f"Optimizer's stopping condition, {registration_method.GetOptimizerStopConditionDescription()}"
    )
    return (final_transform, registration_method.GetMetricValue())

# -------- Setting up initial transform ----------------------------
initial_transform = sitk.CenteredTransformInitializer(
    fixed_image,
    moving_image,
    sitk.Euler3DTransform(),
    sitk.CenteredTransformInitializerFilter.MOMENTS,
)
registration_method = sitk.ImageRegistrationMethod()
registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(0.5)
registration_method.SetInterpolator(sitk.sitkLinear)
# The order of parameters for the Euler3DTransform is [angle_x, angle_y, angle_z, t_x, t_y, t_z]. The parameter
# sampling grid is centered on the initial_transform parameter values, that are all zero for the rotations. Given
# the number of steps and their length and optimizer scales we have:
# angle_x = 0
# angle_y = -pi, 0, pi
# angle_z = -pi, 0, pi
registration_method.SetOptimizerAsExhaustive(
    numberOfSteps=[0, 1, 1, 0, 0, 0], stepLength=np.pi
)
registration_method.SetOptimizerScales([1, 1, 1, 1, 1, 1])

# Perform the registration in-place so that the initial_transform is modified.
registration_method.SetInitialTransform(initial_transform, inPlace=True)
registration_method.Execute(fixed_image, moving_image)

print("best initial transformation is: " + str(initial_transform.GetParameters()))

# -------- Calculate final transform 
final_transform, _ = multires_registration(fixed_image, moving_image, initial_transform)

```

1. My questions:  
(1) I don’t get `registration_method.SetOptimizerAsExhaustive(numberOfSteps=[0, 1, 1, 0, 0, 0], stepLength=np.pi)` in setting up the initial transform. Can someone explain what does this do specifically? I don’t get the explanation given in the notebook. What are the 6 parameters in the `numberOfSteps` related to?

(2) Similarly to above, I don’t know `registration_method.SetOptimizerScales([1, 1, 1, 1, 1, 1])`. What is meant by “Scales” in registration?

(3) In setting up initial transform, there is `registration_method.SetInitialTransform(initial_transform, inPlace=True)`. On the other hand, it appears again in `multires_registration` function, but with `inPlace=False`. Why?

(4) In `multires_registration` function, there is `SetShrinkFactorsPerLevel(shrinkFactors=[1, 1, 1])`. What does it do? What are the 3 parameters?

And what is `SetSmoothingSigmasPerLevel(smoothingSigmas=[1, 1, 1])`? Is it related to some sort of interpolation when shrinking is done?

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [September 19, 2024, 5:56pm UTC](https://discourse.itk.org/t/need-help-understanding-codes-from-sitk-notebook/7228/2 "2024-09-19T17:56:02Z")

</div>

Hello @Learner,

Welcome to ITK/SimpleITK!

When using the Exhaustive optimization approach we place a grid in the transformation parameter space and evaluate the similarity metric for all transformations defined by the grid.

The grid is defined by the `numberOfSteps`, `stepLength` parameters and the `SetOptimizerScales` method. If `i` is the transformation parameter index (for example, i==2 for Euler3DTransform, angle\_x, angle\_y, angle\_z, t\_x, t\_y, t\_z, means we are dealing with angle\_z).

The grid in parameter space is defined as follows  
[initial\_transform.GetParameters()[i] - optimizer\_scales[i] \cdot stepLength \cdot numberOfSteps[i],…,  
initial\_transform.GetParameters(),…,  
initial\_transform.GetParameters()+optimizer\_scales[i] \cdot stepLength \cdot numberOfSteps[i]]

With respect to the remaining questions, please see the [SimpleITK online Tutorial](https://simpleitk.org/TUTORIAL/). The videos may be a bit outdated, but they mostly match the current toolkit status. If after going through the tutorial you still have questions, post them on the forum and we’ll do our best to help you.
