refine_orientation#

de_ebsd.index.refine.refine_orientation(patterns, master, detector, rotations, pattern_center=None, refine_pattern_center=False, method='adam', n_iterations=None, learning_rate=0.02, pattern_center_learning_rate=None, damping=0.001, directions=None, device=None, keep_best=True, return_history=False)[source]#

Refine rotations (and optionally the pattern center) by autograd.

Sharpens a coarse seed to sub-grid-cell accuracy by maximizing a spherical masked NCC between the back-projected pattern E(n) and the master sampled at the trial-rotated directions M(R n), with R = R0 . dR(w) for a differentiable rotation-vector correction w. The whole stack is refined in one parallel optimization on the master’s device.

Parameters:
patterns

A detector image (H, W) or stack (Np, H, W), numpy or torch.

master, detector

The continuous de_ebsd.sim.MasterPattern and the EBSDDetector whose pixel -> direction map is inverted (differentiably in the pattern center) to build E(n).

rotations

Seed orix.quaternion.Rotation, typically the coarse index output.

pattern_center

None uses detector.pattern_center. A (3,) value shares one center across the stack – the common, fully-vectorized path; (Np, 3) gives a per-pattern center and loops the back-projection.

refine_pattern_center

Refine the pattern center jointly with the orientation. Forces method="adam", since the LM path is orientation-only.

method

"adam" (default) is first-order. "lm" is Levenberg-Marquardt with an analytic Jacobian, reaching the same sub-degree accuracy in ~10 steps instead of ~60 (~2.3x faster at equal accuracy on real data). LM is orientation-only and assumes the default in-FOV directions.

n_iterations

Step budget. None resolves per method: 60 for Adam, 12 for LM.

learning_rate

Adam step size for the rotation vector, in radians. The key stability knob: too large a step overshoots the shallow, noisy basin of real patterns and diverges. 0.02 is stable on real data; use ~0.01 for noisy scans.

pattern_center_learning_rate

Adam step size for the pattern center (default learning_rate / 5, since its natural scale is finer). Ignored unless refine_pattern_center.

damping

Initial LM damping, adapted per pattern each step (x0.5 accepted, x3 rejected). LM only.

directions

Sphere directions (M, 3) the NCC is evaluated over. None uses the detector’s in-FOV pixel directions, where every point contributes – ~3x faster and more accurate than a whole-sphere set that is mostly masked away. method="lm" requires an all-in-FOV set; the default satisfies this, but a custom non-FOV set is unsafe for LM (use Adam, whose masked NCC handles it).

device

Defaults to master.data.device; otherwise everything is moved there.

keep_best

Never return an orientation worse than the seed, making refinement monotone. This removes the stray outliers gradient refinement can introduce on low-quality real patterns.

return_history

Also return the per-step NCC trajectory.

Returns:
rotationorix.quaternion.Rotation

The refined orientation(s), in the convention MasterPattern.project consumes.

scoretorch.Tensor

Final NCC per pattern, in [-1, 1]; >= the coarse score. This is what index_scan(refine=True) stores as prop["quality"].

pattern_centertorch.Tensor

Only when refine_pattern_center: the refined pattern center, shaped like the input.

historytorch.Tensor

Only when return_history: the NCC at every step, (n_iterations, Np), with history[0] the seed score.