Testing different optimizer options in nipy's HistogramRegistration

Hi there. I’m hoping some nipy image registration experts can help me with this.


I’m working on some Python code for real-time fMRI analysis, specifically fMRI volume realignment. I’m using the HistogramRegistration class in nipy for 6DOF rigid body transform estimation and registration. I wanted to see how long this takes to execute per volume (important for real-time processing), and I started digging into the different options for the optimize method to compare their execution time and registration results.


A notebook with my code is available on Github and there also a compute environment on Binder. (note, after opening the main notebook in Binder you might have to pip install nipy to be able to run the code)

Description of problem

I’m estimating the 6 realignment parameters for registering an arbitrary volume in the time series to the first volume (the template). I’m first looping through the optimization options ['powell', 'steepest', 'cg', 'bfgs', 'simplex']. For some reason that I don’t understand yet, 'steepest' seems to fail. When excluding that from the options, all of the rest seem to converge, although only 'powell' yields sensible realignment parameters, while the rest all yield zeros.

This is a copy from my script output when testing ['powell', 'cg', 'bfgs', 'simplex'] in that order. The registration time array shows the 4 respective execution times in seconds, the realignment params array shows the realignment parameters (columns) for each optimization respective method (rows):

Registration summary:

Registration time per 'opt' method:
[0.4186708927154541, 0.13682198524475098, 0.1139068603515625, 0.11966705322265625]

Realignment params per 'opt' method:
[[ 0.2188504   0.5729578   0.5729578  -0.30057813 -0.20767556  0.381966  ]
 [ 0.          0.          0.          0.          0.          0.        ]
 [ 0.          0.          0.          0.          0.          0.        ]
 [ 0.          0.          0.          0.          0.          0.        ]]


So my question is, does someone have an explanation for why this would happen, i.e. who would one method work and the rest return zeroes? I am not an expert and might be missing something obvious. Like, maybe the optimization methods that I’m trying out aren’t meant to be used for my use case? Or I’m using the methods incorrectly? Any feedback would be great, thanks!