Feature: numeric gradient determination on magnetic fieldmaps with only field values #48
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This introduces numeric gradient determination (for use with adiabatic trajectories) in magnetic fieldmaps that have only field values. The gradient calculation aims to reuse as many of the regular interpolation infrastructure as possible, using the same point sets, but will be one order less in the derivative dimension (nearest neighbor therefore has no gradient).
Due to slight overlap, this uses some of the functionality in #46 (the
magnetic_gradient_numerical
attribute), but either should be possible to merge first.Implementation
KMagfieldMapVTK::GetValue
, in particular the implementations inKLinearInterpolationMagfieldMapVTK
andKCubicInterpolationMagfieldMapVTK
, takes a booleangradient
that will return the gradient instead of the value.For the linear interpolation,
_trilinearInterpolate
takes anint d[]
argument which contains the derivatives in each dimension (only 0 and 1 supported, for zeroth and first derivative). So,int d[3] = {0, 0, 1}
will result in the z derivative, andint d[3] = {0, 1, 1}
(unused) would result in the yz double derivative. Depending on which derivative is requested, this is passed to the_bilinearInterpolate
or_linearInterpolate
stages, as appropriate. Ultimately, the linear interpolation kernelp[1] - p[0]
is used for the derivative in the requested direction, wherep[0] + x * (p[1] - p[0])
is used when only the value is requested.For the cubic interpolation, a very similar approach results in a cubic interpolation convolution kernel for the derivative that is
0.5 * (p[2] - p[0]) + 2. * x * (2. * p[0] - 5. * p[1] + 4. * p[2] - p[3] + 3. * x * (3. * (p[1] - p[2]) + p[3] - p[0]))
.Tests
I verified on a fieldmap with only field value that this reproduces the output of the numerical gradient calculation in the
root_magfield_painter
for both linear and cubic interpolation cases. Note #47, though.