Constraints#

Constraints are used to filter acceptable solutions computed by a Solver forward() method. One or more constraints (ConstraintBase), together with a choice of operating mode, are used to control the over-determined transformation from \(hkl\) to motor angles.

Note

Relation to cut points in other software (SPEC cuts): In SPEC, a cut point is a branch point that sets where an angle wraps around (e.g., -180[-180, +180)), controlling motor travel direction rather than filtering solutions. hklpy2 LimitsConstraint is a post-computation filter that discards solutions outside a range. The two overlap in effect when the constraint window matches the cut-point interval, but the mechanisms differ.

Show the current constraints#

Start with a diffractometer. This example starts with E6C, as shown in the Quickstart.

1>>> import hklpy2
2>>> sixc = hklpy2.creator(name="sixc", geometry="E6C", solver="hkl_soleil")

Show the constraints:

1>>> sixc.core.constraints
2['-180.0 <= mu <= 180.0', '-180.0 <= omega <= 180.0', '-180.0 <= chi <= 180.0', '-180.0 <= phi <= 180.0', '-180.0 <= gamma <= 180.0', '-180.0 <= delta <= 180.0']

Change a constraint#

Only accept forward() solutions where omega \(>= 0\).

1>>> sixc.core.constraints["omega"].low_limit
2-180.0
3>>> sixc.core.constraints["omega"].low_limit = 0
4>>> sixc.core.constraints["omega"]
50 <= omega <= 180.0

Apply axis cuts#

Only accept forward() solutions where chi is between \(\\pm90\):

1>>> sixc.core.constraints["chi"].limits
2(-180.0, 180.0)
3>>> sixc.core.constraints["chi"].limits = -90, 90
4>>> sixc.core.constraints["chi"].limits
5(-90.0, 90.0)

Limited range#

Only accept forward() solutions where mu is near zero. Setting both limits to the same value (or very close values) effectively restricts that axis to a single position:

1>>> sixc.core.constraints["mu"].limits
2(-180.0, 180.0)
3>>> sixc.core.constraints["mu"].limits = -0.01, 0.01   # narrow range
4>>> sixc.core.constraints["mu"].limits
5(-0.01, 0.01)

Tip

Constraints filter solutions after the solver computes them. If you want the solver to use a specific value for a constant axis during forward() computation (rather than the current motor position), use presets instead.

Preset (frozen) axes#

In SPEC, the freeze command holds an axis at a fixed value during forward() computation. In hklpy2, this is done with presets.

A preset tells the solver which value to use for a constant axis instead of the current motor position. Presets do not move any motor.

Choose a mode where the axis is constant, then set a preset:

1>>> sixc.core.mode = "bissector_vertical"   # mu and gamma are constant
2>>> sixc.core.constant_axis_names
3['mu', 'gamma']
4>>> sixc.core.presets = {"gamma": 0}         # solver uses gamma=0
5>>> sixc.forward(1, 0, 0)                    # no motor is moved

To release a single preset (SPEC unfreeze):

1>>> sixc.core.presets.pop("gamma")           # remove one preset
20
3>>> sixc.core.presets
4{}

To release all presets at once:

1>>> sixc.core.presets = {}                  # remove all presets for current mode

See also

How to Use Presets — complete how-to guide for presets.