BH_multi_gridCoordinates.m - single responsibility principle
At the moment, BH_multi_gridCoordinates.m has to much responsibility, slowing things down and reducing clarity. Below is an example showing how we could refactor the code. This is not backward compatible.
EMC_multi_gridCoordinates:
This function should only be used for creating grids later used for interpolation. The interpn function can accept the vectorCoordinates, which allows to reduce the computation on the grids.
shifts: subtract the shifts to the vectors. The grids should stay unshifted. This is one of the reasons why this function should not be used for creating masks: now the gridCoordinates are never shifted, the vectors are.
offsets (change center of rotation): subtract the offsets to the vectors. Use these shifted vectors to create the grids.
scaling: scale the rotation matrix directly, this has the effect to scale the image/volume before rotation. No need to multiply the grids by the scaling factor anymore.
shifts and mag changes are applied before rotations. I think that is the convention mostly used...
the TRANS input cell allows optional inputs. No need to add all the directives (rotm, direction, origin, etc.), see help EMC_multi_gridCoordinates.
I am not sure how to use BH_multi_gridCoordinates actually, because it looks like regardless of the DIRECTION (forward or inverse), the rotation is always CC on the final interpolated image. EMC_multi_gridCoordinates can switch between both DIRECTION, but by default apply a CCW rotation. The shifts and scaling are also switched depending on the DIRECTION, of course.
As a result, the transformation consists only into a matrix multiplication between the rotm and the coordinates.
EMC_multi_gridMasks:
This function take over the coordinates systems part of BH_multi_gridCoordinates and should therefore be used to create masks/filters.
Radial grid: no need to call ndgrid. This saves memory and only the vectors are squared.
gX = vX'.^2 + vY.^2 + reshape(vZ, 1, 1, []).^2;
flgIsotrope: Stretch the grid values to the smallest dimensions.
EMC_multi_vectorCoordinates:
Compute the vectorCoordinates. Both EMC_multi_gridMasks and EMC_multi_gridCoordinates use this function.
By shifting the boundaries used to create the vectors, it can very efficiently shift the output vectors.
the ORIGIN is now explicitly defined. The function uses an offset to switch between conventions. The overload of computing the offsets should be negligible. See help EMC_multi_vectorCoordinates for more details.
Are you sure about the vector coordinates when flgOrigin = 0? Here is what you do: flgOrigin = 0: 6pixels(0, 1, 2, 3, -2, -1) but shouldn't it be 6pixels(0, 1, 2, -3, -2, -1)? For now, I did as I think is correct. I'll wait for your answer.
flgOrigin = -1 and -2: I don't understand the vectors in that case. Could you explain?
Add an option (like flgHalf = -1) to compute only 1/4 (or 1/8 if 3d) of the grids/vectors. This could be useful for masks and filters that usually have a C4 symmetry. To regenerate the full grids, we can then have a function that takes this 1/4|8 grid and the ORIGIN/flgShiftOrigin, to compute the entire grid with the desired origin. It should be faster, specially for sphere/cylinder masks and filters where computing the taper can be expensive...
This pull request is just to illustrate the improvements that could be done on BH_multi_gridCoordinates. Using these new functions require some important changes to the rest code, as the inputs are different and some conventions were changed (flgShiftOrigin for example).
If you agree with some ideas, I can modify BH_multi_gridCoordinates while keeping backward compatibility, but I think it would be beneficial to split it into multiple functions.
BH_multi_gridCoordinates.m - single responsibility principle
At the moment, BH_multi_gridCoordinates.m has to much responsibility, slowing things down and reducing clarity. Below is an example showing how we could refactor the code. This is not backward compatible.
EMC_multi_gridCoordinates: This function should only be used for creating grids later used for interpolation. The interpn function can accept the vectorCoordinates, which allows to reduce the computation on the grids.
As a result, the transformation consists only into a matrix multiplication between the rotm and the coordinates.
EMC_multi_gridMasks: This function take over the coordinates systems part of BH_multi_gridCoordinates and should therefore be used to create masks/filters.
EMC_multi_vectorCoordinates: Compute the vectorCoordinates. Both EMC_multi_gridMasks and EMC_multi_gridCoordinates use this function.
This pull request is just to illustrate the improvements that could be done on BH_multi_gridCoordinates. Using these new functions require some important changes to the rest code, as the inputs are different and some conventions were changed (flgShiftOrigin for example). If you agree with some ideas, I can modify BH_multi_gridCoordinates while keeping backward compatibility, but I think it would be beneficial to split it into multiple functions.