kappa4cv — Kappa Four-Circle (Synchrotron)#

Four-circle kappa diffractometer, vertical scattering plane. The chi circle is replaced by a kappa axis tilted at α = 50° from the outer komega axis toward the equivalent Eulerian chi axis (issue #241; see How the kappa axis is defined below).

Walko (2016) designation: S3D1 (kappa)

Coordinate basis: Busing & Levy (BASIS_BL): transverse=+x, longitudinal=+y, vertical=+z.

Quick start#

import ad_hoc_diffractometer as ahd

g = ahd.presets.kappa4cv()
g.wavelength = 1.0  # Å
print(g.summary())

Pre-built geometry definition#

This geometry is defined by the kappa4cv() factory function — see the source for the complete stage and mode configuration.

Stage layout#

Static fallback (click to expand if the interactive figure above is blank)

kappa4cv stage layout

Sample stages (base first):

Stage

Axis

Handedness

Parent

komega

−transverse (−x BL)

left-handed

base

kappa

−x · cos α + ŷ · sin α (α = 50°)

right-handed

komega

kphi

−transverse (−x BL)

left-handed

kappa

Detector stages (base first):

Stage

Axis

Handedness

Parent

ttheta

−transverse (−x BL)

left-handed

base

How the kappa axis is defined#

The kappa rotation axis lies in the plane spanned by the outer komega axis and the equivalent Eulerian chi axis, tilted by α from komega toward the chi-equivalent direction:

\[ \hat{n}_{\kappa} \;=\; \cos\alpha \cdot \hat{n}_{\kappa\omega} \;+\; \sin\alpha \cdot \hat{n}_{\chi,\,\text{eq}}. \]

For kappa4cv (BL convention) this is

\[ \hat{n}_{\kappa} \;=\; \cos 50° \cdot (-\hat{x}) \;+\; \sin 50° \cdot (+\hat{y}) \;=\; (-0.643,\, 0.766,\, 0). \]

This differs from earlier versions of the package, which set the kappa axis from a textbook formula vertical · cos α + transverse · sin α regardless of the actual komega orientation. The earlier formula is correct only when komega is along +vertical; it is not correct for kappa4cv, kappa4ch, or kappa6c, all of which encode komega along a non-vertical signed axis. The mismatch caused a silent solver gap that returned "No solutions" for several physically reachable reflections; see issue #241 and KappaPseudoAngleConvention for the full derivation and rationale.

Virtual Eulerian angles omega, chi, phi are mapped to / from the real motors via the geometry-aware decomposition in eulerian_to_kappa_axes() and kappa_to_eulerian_axes(). The older Walko-textbook helpers eulerian_to_kappa() and kappa_to_eulerian() are retained as reference implementations of the published closed form but are not used inside the solver.

Diffraction modes#

Each mode is a ConstraintSet of 1 constraint (N − 3 = 1 for N = 4 DOF). See Switch Diffraction Modes for usage and Work with Constraints and Diffraction Modes for changing constraint values at run time.

bisecting (default)#

VirtualBisectConstraint: omega_virtual = ttheta / 2 enforced on the virtual Eulerian omega pseudoangle. The kappa motor triple (komega, kappa, kphi) satisfies this constraint via the geometry-aware eulerian_to_kappa_axes() decomposition (issue #241).

Computed

komega, kappa, kphi, ttheta

Constant during forward()

fixed_kphi#

SampleConstraint: kphi held at declared value (default 0°) — real stage, no kappa inversion needed. The caller chooses the value by constructing a ConstraintSet.

Computed

komega, kappa, ttheta

Constant during forward()

kphi

fixed_omega#

SampleConstraint: Fix the virtual Eulerian omega at declared value (default 0°). Solved analytically via the equivalent-Eulerian dispatch (issue #241) — the caller chooses the value by constructing a ConstraintSet.

Computed

komega, kappa, kphi, ttheta

Constant during forward()

omega (virtual)

fixed_chi#

SampleConstraint: Fix the virtual Eulerian chi at declared value (default 90°). The caller chooses the value by constructing a ConstraintSet.

Computed

komega, kappa, kphi, ttheta

Constant during forward()

chi (virtual)

fixed_phi#

SampleConstraint: Fix the virtual Eulerian phi at declared value (default 0°). The caller chooses the value by constructing a ConstraintSet.

Computed

komega, kappa, kphi, ttheta

Constant during forward()

phi (virtual)

fixed_psi#

ReferenceConstraint: azimuthal angle ψ validation filter. Set g.azimuthal_reference = (h, k, l) before calling forward(). Returns bisecting solutions only when the natural ψ for (h,k,l) matches the stored target. See Surface Geometry and the Reference Vector.

Computed

komega, kappa, kphi, ttheta

Extras (input)

n̂ (reference vector), ψ (target azimuth, degrees)

Extras (output)

psi (computed azimuth)

double_diffraction#

Full 4D simultaneous solver: finds motor angles where both the primary (h₁,k₁,l₁) and secondary (h₂,k₂,l₂) reflections satisfy the Ewald sphere condition. Set mode.extras['h2'], ['k2'], ['l2'] before calling forward().

Computed

komega, kappa, kphi, ttheta

Extras (input)

h₂, k₂, l₂ (secondary reflection Miller indices)

API reference#

References#