FAQ#

Frequently Asked Questions

General

  1. Is hklpy2 ophyd v1 only, or can it be used with ophyd async?

  2. Is there a way to use hklpy2 without real hardware?

  3. What units does hklpy2 use?

  4. import gi raises an ImportError when starting the bluesky queue-server.

Computation

  1. forward() (or cahkl()) returns no solutions when I expect some.

  2. What is the difference between constraints and presets?

  3. The UB matrix looks wrong, or pa() and configuration show different values.

SPEC users

  1. What are the hklpy2 equivalents of SPEC’s wh and pa?

  2. Can I perform azimuthal (ψ) scans?


Is hklpy2 ophyd v1 only, or can it be used with ophyd async?#

hklpy2 uses ophyd v1 (synchronous). Ophyd async (v2) is not yet supported. See issue #334 for a feasibility analysis of migrating to ophyd-async.


Is there a way to use hklpy2 without real hardware?#

Yes. Simulators are easy to create for any defined solver and geometry. Use creator() without supplying EPICS PV names — all real axes default to soft (simulated) positioners:

import hklpy2
e4cv = hklpy2.creator(name="e4cv")

See also

Tutorial: Your First Diffractometer — full guided walkthrough using a simulated E4CV diffractometer.

Example 4-circle diffractometer using creator() — worked demonstration.


What units does hklpy2 use?#

Quantity

Default unit

Notes

Wavelength

Å (angstroms)

Configurable; energy conversion available for X-rays via WavelengthXray.

Real axes (angles)

degrees

All motor positions reported and accepted in degrees.

Reciprocal-space axes (h, k, l)

reciprocal of wavelength unit (Å-1)

Dimensionless Miller indices when wavelength is in Å.

Lattice parameters (a, b, c)

Å (angstroms)

Must match the wavelength unit.

Lattice angles (α, β, γ)

degrees


import gi raises an ImportError when starting the bluesky queue-server.#

This is tracked as issue #69. The problem occurs on linux 64-bit systems when the libgobject shared library is not on LD_LIBRARY_PATH. Either of these approaches works around it until it is resolved upstream:

  1. Set the environment variable when starting the queue-server:

    LD_LIBRARY_PATH=${CONDA_PREFIX}/lib start-re-manager <options>
    
  2. Configure the conda environment to set this on activation:

    conda env config vars set LD_LIBRARY_PATH="${CONDA_PREFIX}/lib"
    

forward() (or cahkl()) returns no solutions when I expect some.#

The most common causes, in order of likelihood:

  1. Constraints are too narrow. Check diffractometer.core.constraints. Each real axis has a low_limit and high_limit; the solver silently discards any candidate solution where an axis falls outside those limits. Widen the range for the blocking axis:

    e4cv.core.constraints["omega"].limits = -180, 180
    
  2. The requested \(hkl\) is outside the Ewald sphere at the current wavelength. Use a shorter wavelength (higher energy) or request a lower-angle reflection.

  3. Axes out of order in axes_xref. If you supplied real-axis names in a different order than the solver expects, the cross-reference map silently swaps axes. A swapped detector angle and sample rotation angle will produce Q = 0, yielding no valid solutions. Inspect diffractometer.core.axes_xref and, if necessary, supply _real=["name1", "name2", ...] to creator() in solver order. See Reals supplied in a different order than the solver expects.

See also

How to Use Constraints — set limits, cut points, and write custom constraints.

Constraints, Presets


What is the difference between constraints and presets?#

Both involve holding real axes at specific values, but they act at different points in the forward() computation:

Presets

Constraints

When

Before computation — the solver assumes this value for a constant axis instead of the current motor position.

After computation — solutions where an axis falls outside the allowed range are discarded.

Effect on motors

None — no motor moves.

None — no motor moves.

Typical use

SPEC freeze: hold phi=0 while the solver finds omega, chi, tth.

Restrict chi to ±90° to avoid sample collision.

See also

How to Use Constraints — set axis limits and cut points.

How to Use Presets — freeze an axis at a fixed value during forward().


The UB matrix looks wrong, or pa() and configuration show different values.#

Two common causes:

  1. Axis mapping is swapped. If axes_xref has detector angles wired to sample-rotation slots (or vice versa), the UB calculation receives the wrong angles and produces a degenerate or incorrect matrix. Verify diffractometer.core.axes_xref matches your physical wiring. See Reals supplied in a different order than the solver expects.

  2. Display precision. pa() rounds values for readability; the stored matrix retains full floating-point precision. A sign difference (e.g. +0.0101 vs. -0.0101) on a near-zero element is a display rounding artefact. Retrieve the full matrix via diffractometer.sample.UB.

See also

How to Compute and Set the UB Matrix — add reflections, compute, inspect, and refine the UB matrix.


What are the hklpy2 equivalents of SPEC’s wh and pa?#

SPEC command

hklpy2 equivalent

Notes

wh

diffractometer.wh()

Shows current pseudos and reals. Pass full=True for more detail.

pa

diffractometer.core.pa()

Full orientation report: lattice, reflections, UB matrix, constraints, presets.

freeze / unfreeze

How to Use Presets

Use diffractometer.core.presets.

cuts (cut points)

Constraints

Use diffractometer.core.constraints.

ca / cahkl

diffractometer.forward(h, k, l)

Returns all solutions; the diffractometer’s forward() picks one.

ubr / or0 / or1

add_reflection()

Record an orientation reflection.

See SPEC commands in hklpy2 for a comprehensive cross-reference.


Can I perform azimuthal (ψ) scans?#

Azimuthal scans — rotating the sample about the scattering vector \(\mathbf{Q}\) at fixed \(hkl\) — are supported using scan_extra() with the psi_constant mode of the hkl_soleil solver.

See also

How to Perform an Azimuthal (ψ) Scan — step-by-step how-to guide for E4CV, including realistic motor constraints and pre-scan verification.

hkl_soleil E6C psi axis — worked E6C demonstration, including the inverse case (reading ψ from real motor positions).

issue #188 — tracking issue; a convenience wrapper scan_psi() may be added in a future release.