.. _geometries: ========== Geometries ========== Each solver registered under the ``hklpy2.solver`` entry-point group exposes one or more named geometries. The geometry name is passed to the solver when it is instantiated by hklpy2. .. contents:: On this page :local: :depth: 1 .. _geometries.ad_hoc: ``ad_hoc`` solver ----------------- :class:`~hklpy2_solvers.ad_hoc_solver.AdHocSolver` Wraps `ad_hoc_diffractometer `_ (Jemian 2026). The ``ad_hoc`` solver discovers geometries dynamically from the `ad_hoc_diffractometer `_ library. All geometries registered in the library's geometry registry (including via entry points) are automatically available. The pseudo axes are always ``h``, ``k``, ``l``. .. _geometry.fourcv: fourcv ~~~~~~ Busing & Levy (1967) four-circle Eulerian diffractometer (vertical scattering plane, transverse ttheta, synchrotron). See `ad_hoc_diffractometer fourcv `_. .. list-table:: ``fourcv`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``fourcv`` * - Real axes - ``omega``, ``chi``, ``phi``, ``ttheta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting`` .. list-table:: ``fourcv`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting`` - omega - chi, phi, ttheta - * - ``fixed_chi`` - chi - omega, phi, ttheta - * - ``fixed_phi`` - phi - omega, chi, ttheta - * - ``fixed_omega`` - omega - chi, phi, ttheta - * - ``fixed_psi`` - *(none)* - omega, chi, phi, ttheta - n_hat, psi * - ``double_diffraction`` - *(none)* - omega, chi, phi, ttheta - h2, k2, l2 .. _geometry.fourch: fourch ~~~~~~ Busing & Levy (1967) four-circle Eulerian diffractometer (horizontal scattering plane, vertical ttheta, laboratory). See `ad_hoc_diffractometer fourch `_. .. list-table:: ``fourch`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``fourch`` * - Real axes - ``omega``, ``chi``, ``phi``, ``ttheta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting`` .. list-table:: ``fourch`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting`` - omega - chi, phi, ttheta - * - ``fixed_chi`` - chi - omega, phi, ttheta - * - ``fixed_phi`` - phi - omega, chi, ttheta - * - ``fixed_omega`` - omega - chi, phi, ttheta - * - ``fixed_psi`` - *(none)* - omega, chi, phi, ttheta - n_hat, psi * - ``double_diffraction`` - *(none)* - omega, chi, phi, ttheta - h2, k2, l2 .. _geometry.psic: psic ~~~~ You (1999) 4S+2D six-circle diffractometer (transverse detector, vertical scattering plane, synchrotron). See `ad_hoc_diffractometer psic `_. .. list-table:: ``psic`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``psic`` * - Real axes - ``mu``, ``eta``, ``chi``, ``phi``, ``nu``, ``delta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting_vertical`` .. list-table:: ``psic`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting_vertical`` - eta, mu, nu - chi, phi, delta - * - ``fixed_phi_vertical`` - mu, nu, phi - eta, chi, delta - * - ``fixed_chi_vertical`` - chi, mu, nu - eta, phi, delta - * - ``fixed_alpha_i_vertical`` - mu, nu - eta, chi, phi, delta - n_hat, alpha_i, beta_out * - ``fixed_beta_out_vertical`` - mu, nu - eta, chi, phi, delta - n_hat, alpha_i, beta_out * - ``alpha_eq_beta_vertical`` - mu, nu - eta, chi, phi, delta - n_hat, alpha_i, beta_out * - ``fixed_psi_vertical`` - mu, nu - eta, chi, phi, delta - n_hat, psi * - ``fixed_alpha_i_fixed_chi_fixed_phi`` - chi, phi - mu, eta, nu, delta - n_hat, alpha_i, beta_out * - ``fixed_omega_vertical`` - mu, nu - eta, chi, phi, delta - * - ``double_diffraction_vertical`` - mu, nu - eta, chi, phi, delta - h2, k2, l2 * - ``bisecting_horizontal`` - delta, eta, mu - chi, phi, nu - * - ``fixed_phi_horizontal`` - delta, eta, phi - mu, chi, nu - * - ``fixed_chi_horizontal`` - chi, delta, eta - mu, phi, nu - * - ``fixed_alpha_i_horizontal`` - delta, eta - mu, chi, phi, nu - n_hat, alpha_i, beta_out * - ``fixed_beta_out_horizontal`` - delta, eta - mu, chi, phi, nu - n_hat, alpha_i, beta_out * - ``alpha_eq_beta_horizontal`` - delta, eta - mu, chi, phi, nu - n_hat, alpha_i, beta_out * - ``fixed_psi_horizontal`` - delta, eta - mu, chi, phi, nu - n_hat, psi * - ``fixed_omega_horizontal`` - delta, eta - mu, chi, phi, nu - * - ``double_diffraction_horizontal`` - delta, eta - mu, chi, phi, nu - h2, k2, l2 * - ``zone_vertical`` - mu, nu - eta, chi, phi, delta - * - ``zone_horizontal`` - delta, eta - mu, chi, phi, nu - * - ``lifting_detector_phi`` - chi, eta, mu - phi, nu, delta - * - ``lifting_detector_mu`` - chi, eta, phi - mu, nu, delta - * - ``lifting_detector_eta`` - chi, mu, phi - eta, nu, delta - .. _geometry.sixc: sixc ~~~~ Lohmeier & Vlieg (1993) six-circle surface diffractometer. See `ad_hoc_diffractometer sixc `_. .. list-table:: ``sixc`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``sixc`` * - Real axes - ``alpha``, ``omega``, ``chi``, ``phi``, ``delta``, ``gamma`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting_4c`` .. list-table:: ``sixc`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting_4c`` - alpha, gamma, omega - chi, phi, delta - * - ``fixed_gamma_5c`` - alpha, gamma, omega - chi, phi, delta - * - ``fixed_alpha_5c`` - alpha, gamma, omega - chi, phi, delta - * - ``fixed_alpha_zaxis`` - alpha, chi - omega, phi, delta, gamma - n_hat, alpha_i, beta_out * - ``fixed_beta_zaxis`` - chi, gamma - alpha, omega, phi, delta - n_hat, alpha_i, beta_out * - ``alpha_eq_beta_zaxis`` - chi, phi - alpha, omega, delta, gamma - n_hat, alpha_i, beta_out .. _geometry.fivec: fivec ~~~~~ Five-circle geometry (four-circle with additional mu tilt). See `ad_hoc_diffractometer fivec `_. .. list-table:: ``fivec`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``fivec`` * - Real axes - ``mu``, ``omega``, ``chi``, ``phi``, ``ttheta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting_4c`` .. list-table:: ``fivec`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting_4c`` - mu, omega - chi, phi, ttheta - * - ``fixed_chi`` - chi, mu - omega, phi, ttheta - * - ``fixed_phi`` - mu, phi - omega, chi, ttheta - * - ``fixed_mu`` - mu, omega - chi, phi, ttheta - * - ``fixed_omega_noncoplanar`` - mu, omega - chi, phi, ttheta - .. _geometry.kappa4cv: kappa4cv ~~~~~~~~ Kappa four-circle vertical-scattering geometry. See `ad_hoc_diffractometer kappa4cv `_. .. list-table:: ``kappa4cv`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``kappa4cv`` * - Real axes - ``komega``, ``kappa``, ``kphi``, ``ttheta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting`` .. list-table:: ``kappa4cv`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting`` - omega (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_kphi`` - kphi - komega, kappa, ttheta - * - ``fixed_omega`` - omega (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_chi`` - chi (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_phi`` - phi (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_psi`` - *(none)* - komega, kappa, kphi, ttheta - n_hat, psi * - ``double_diffraction`` - *(none)* - komega, kappa, kphi, ttheta - h2, k2, l2 .. _geometry.kappa4ch: kappa4ch ~~~~~~~~ Kappa four-circle horizontal-scattering geometry. See `ad_hoc_diffractometer kappa4ch `_. .. list-table:: ``kappa4ch`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``kappa4ch`` * - Real axes - ``komega``, ``kappa``, ``kphi``, ``ttheta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting`` .. list-table:: ``kappa4ch`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting`` - omega (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_kphi`` - kphi - komega, kappa, ttheta - * - ``fixed_omega`` - omega (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_chi`` - chi (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_phi`` - phi (virtual) - komega, kappa, kphi, ttheta - * - ``fixed_psi`` - *(none)* - komega, kappa, kphi, ttheta - n_hat, psi .. _geometry.kappa6c: kappa6c ~~~~~~~ Kappa six-circle geometry (psic-style outer axes, transverse detector, synchrotron). See `ad_hoc_diffractometer kappa6c `_. .. list-table:: ``kappa6c`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``kappa6c`` * - Real axes - ``mu``, ``komega``, ``kappa``, ``kphi``, ``nu``, ``delta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``bisecting_vertical`` .. list-table:: ``kappa6c`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``bisecting_vertical`` - mu, nu, omega (virtual) - komega, kappa, kphi, delta - * - ``bisecting_horizontal`` - delta, komega, mu - kappa, kphi, nu - * - ``fixed_kphi`` - kphi, mu, nu - komega, kappa, delta - * - ``fixed_mu`` - mu, nu, omega (virtual) - komega, kappa, kphi, delta - * - ``fixed_nu`` - mu, nu, omega (virtual) - komega, kappa, kphi, delta - * - ``fixed_delta`` - delta, komega, mu - kappa, kphi, nu - * - ``lifting_detector_mu`` - komega, mu - kappa, kphi, nu, delta - * - ``lifting_detector_kphi`` - kphi, mu - komega, kappa, nu, delta - * - ``fixed_psi_vertical`` - mu, omega (virtual) - komega, kappa, kphi, nu, delta - n_hat, psi * - ``fixed_psi_horizontal`` - komega, mu - kappa, kphi, nu, delta - n_hat, psi * - ``double_diffraction_vertical`` - mu, nu - komega, kappa, kphi, delta - h2, k2, l2 * - ``double_diffraction_horizontal`` - delta, komega - mu, kappa, kphi, nu - h2, k2, l2 * - ``zone_vertical`` - mu, nu - komega, kappa, kphi, delta - * - ``zone_horizontal`` - delta, komega - mu, kappa, kphi, nu - .. _geometry.zaxis: zaxis ~~~~~ Z-axis four-circle surface diffraction geometry (Bloch 1985). See `ad_hoc_diffractometer zaxis `_. .. list-table:: ``zaxis`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``zaxis`` * - Real axes - ``alpha``, ``Z``, ``delta``, ``gamma`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``zaxis`` (first available) .. list-table:: ``zaxis`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``zaxis`` - *(none)* - alpha, Z, delta, gamma - n_hat, alpha_i, beta_out * - ``reflectivity`` - *(none)* - alpha, Z, delta, gamma - n_hat, alpha_i, beta_out .. _geometry.s2d2: s2d2 ~~~~ Two-sample / two-detector surface diffraction geometry (Evans-Lutterodt & Tang 1995). See `ad_hoc_diffractometer s2d2 `_. .. list-table:: ``s2d2`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``s2d2`` * - Real axes - ``mu``, ``Z``, ``nu``, ``delta`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``fixed_mu`` (first available) .. list-table:: ``s2d2`` operating modes :header-rows: 1 :widths: 25 20 25 30 * - Mode name - Constant stages - writable(s) - extra(s) * - ``fixed_mu`` - mu - Z, nu, delta - * - ``reflectivity`` - *(none)* - mu, Z, nu, delta - n_hat, alpha_i, beta_out Kappa geometries ~~~~~~~~~~~~~~~~ The kappa geometries (:ref:`kappa4cv `, :ref:`kappa4ch `, :ref:`kappa6c `) accept a ``kappa_alpha_deg`` keyword argument when the solver is created. This sets the fixed tilt angle of the kappa arm. The default is 50 degrees. The kappa modes ``fixed_omega``, ``fixed_chi``, and ``fixed_phi`` (and, on ``kappa6c``, ``bisecting_vertical`` / ``fixed_mu`` / ``fixed_nu``) constrain the *equivalent Euler* (virtual) angles rather than the physical kappa motors. Extensibility ~~~~~~~~~~~~~ The ``ad_hoc`` solver discovers geometries dynamically from the `ad_hoc_diffractometer `_ library's registry. New geometries added to the library (including via entry points) are automatically available without changes to the solver code. ---- .. _geometry.diffcalc_4S_2D: ``diffcalc`` solver ------------------- :class:`~hklpy2_solvers.diffcalc_solver.DiffcalcSolver` Wraps `diffcalc-core `_ (You 1999). See the `diffcalc-core documentation `_ for full details of the underlying library. diffcalc_4S_2D ~~~~~~~~~~~~~~ H. You, *J. Appl. Cryst.* **32**, 614 (1999) six-circle geometry. .. list-table:: ``diffcalc_4S_2D`` geometry :header-rows: 1 :widths: 20 80 * - Property - Value * - Geometry name - ``diffcalc_4S_2D`` * - Real axes - ``mu``, ``delta``, ``nu``, ``eta``, ``chi``, ``phi`` * - Pseudo axes - ``h``, ``k``, ``l`` * - Default mode - ``4S+2D bisect_eta_fixed nu_fixed`` Operating modes ^^^^^^^^^^^^^^^ The diffcalc solver selects three diffractometer constraints to fix for each operating mode. This geometry has no extra parameters (``extras`` is always ``{}``). The axes computed by ``forward()`` (``writable``) are all real axes not listed as fixed constraints; the remaining axes are held constant (``axes_c``, derived by hklpy2). .. list-table:: :header-rows: 1 :widths: 35 30 20 15 * - Mode name - Fixed constraints - writable(s) - extra(s) * - ``4S+2D mu_fixed a_eq_b delta_fixed`` - delta=0, a_eq_b, mu=0 - nu, eta, chi, phi - * - ``4S+2D mu_fixed a_eq_b nu_fixed`` - nu=0, a_eq_b, mu=0 - delta, eta, chi, phi - * - ``4S+2D eta_fixed a_eq_b delta_fixed`` - delta=0, a_eq_b, eta=0 - mu, nu, chi, phi - * - ``4S+2D phi_fixed psi_fixed nu_fixed`` - nu=0, psi=0, phi=0 - mu, delta, eta, chi - * - ``4S+2D chi_phi_fixed delta_fixed`` - delta=0, chi=0, phi=0 - mu, nu, eta - * - ``4S+2D mu_eta_fixed delta_fixed`` - delta=0, mu=0, eta=0 - nu, chi, phi - * - ``4S+2D mu_phi_fixed delta_fixed`` - delta=0, mu=0, phi=0 - nu, eta, chi - * - ``4S+2D mu_chi_fixed nu_fixed`` - nu=0, mu=0, chi=0 - delta, eta, phi - * - ``4S+2D eta_phi_fixed nu_fixed`` - nu=0, eta=0, phi=0 - mu, delta, chi - * - ``4S+2D eta_chi_fixed nu_fixed`` - nu=0, eta=0, chi=0 - mu, delta, phi - * - ``4S+2D bisect_mu_fixed delta_fixed`` - delta=0, bisect, mu=0 - nu, eta, chi, phi - * - ``4S+2D bisect_eta_fixed nu_fixed`` - nu=0, bisect, eta=0 - mu, delta, chi, phi - * - ``4S+2D bisect_omega_fixed nu_fixed`` - nu=0, bisect, omega=0 - mu, delta, eta, chi, phi - * - ``4S+2D chi_phi_fixed a_eq_b`` - a_eq_b, chi=0, phi=0 - mu, delta, nu, eta - * - ``4S+2D chi_eta_fixed a_eq_b`` - a_eq_b, chi=0, eta=0 - mu, delta, nu, phi - * - ``4S+2D chi_mu_fixed a_eq_b`` - a_eq_b, chi=0, mu=0 - delta, nu, eta, phi - * - ``4S+2D mu_eta_fixed a_eq_b`` - a_eq_b, mu=0, eta=0 - delta, nu, chi, phi - * - ``4S+2D mu_phi_fixed a_eq_b`` - a_eq_b, mu=0, phi=0 - delta, nu, eta, chi - * - ``4S+2D eta_phi_fixed a_eq_b`` - a_eq_b, eta=0, phi=0 - mu, delta, nu, chi - * - ``4S+2D eta_chi_phi_fixed`` - eta=0, chi=0, phi=0 - mu, delta, nu - * - ``4S+2D mu_chi_phi_fixed`` - mu=0, chi=0, phi=0 - delta, nu, eta - * - ``4S+2D mu_eta_phi_fixed`` - mu=0, eta=0, phi=0 - delta, nu, chi - * - ``4S+2D mu_eta_chi_fixed`` - mu=0, eta=0, chi=0 - delta, nu, phi - Default mode ^^^^^^^^^^^^ The default mode is ``4S+2D bisect_eta_fixed nu_fixed`` (bisect, eta=0, nu=0). This is equivalent to ``bisecting_vertical`` in E6C terminology: scattering stays in the vertical plane with the sample angle bisecting the detector angle (``eta = delta/2``). .. note:: **Bisector modes** Following You (1999) Figure 1 (see also `diffcalc-core docs `_), ``nu`` rotates about the vertical axis and swings the detector **horizontally**; ``delta`` rotates about the horizontal axis and swings the detector **vertically**. The ``bisect`` constraint implements ``eta = delta/2`` (vertical bisector). ``4S+2D bisect_eta_fixed nu_fixed`` (bisect + eta=0 + nu=0) is equivalent to a ``bisecting_vertical`` mode: scattering stays in the vertical plane with the sample bisecting the detector angle. ``4S+2D bisect_mu_fixed delta_fixed`` (bisect + mu=0 + delta=0) is the horizontal counterpart. In the mode name the *bisected sample axis* is stated; the corresponding *detector axis* is implied by the bisect constraint (``delta``). Mode naming convention ^^^^^^^^^^^^^^^^^^^^^^ All mode names follow the pattern ``4S+2D ``, where ``4S+2D`` identifies the You (1999) geometry and the suffix encodes the three fixed constraints: - ``_fixed`` or ``__fixed`` — motor axis (or axes) fixed at zero. - ``a_eq_b`` — reference-vector constraint: azimuthal reference equals scattering vector direction. **Caution:** singular when the scattering vector is parallel to the reference vector; avoid as a default. - ``bisect`` — bisector condition: ``eta = delta/2``. The bisected sample axis (e.g. ``eta``) is named; the detector axis (``delta``) is implied. - ``psi_fixed``, ``omega_fixed`` — azimuthal or omega angle fixed at zero. Extensibility ^^^^^^^^^^^^^ The available constraint names are fixed by diffcalc-core and cannot be changed without modifying that library. Each constraint name has specific mathematical implementation inside diffcalc-core's solver — the name is merely a handle for the underlying algebra that reduces the degrees of freedom during position calculation. A new constraint (e.g. ``mu = nu/2``) would require new code in diffcalc-core, not just a new entry in ``_MODES``. From the user's perspective the mode list is not extensible.