-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
document the support for constraints #300
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
4773133
DOC #290 constraints
prjemian f0528ef
DOC #290 overview
prjemian 6ce42f9
DOC #290 SPEC comparison
prjemian b0398e3
STY #290 whitespace
prjemian 7ea4e5c
DOC #290
prjemian 50f3218
TST #301 test
prjemian d6ca0cb
MNT #301
prjemian 0cbd83a
TST #300 expand test to check the limits
prjemian 0391826
MNT #30 use of value constraint depends on mode
prjemian 2db608a
DOC #290 typo
prjemian eab26b1
DOC #290 missing word
prjemian 34b0029
DOC #290 deprecated `fit` constraint parameter
prjemian 4878a56
DOC #290 sync with changes in `fit` parameter
prjemian fc4cc33
DOC #290
prjemian e5d6440
DOC #290
prjemian cedc797
TST #300 specify the type of tolerance
prjemian 06e0aad
Merge branch 'main' into 290-docs-constraints
prjemian fe1906c
Merge branch 'main' into 290-docs-constraints
prjemian 5967822
Merge branch 'main' into 290-docs-constraints
prjemian File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
.. index:: !constraints | ||
|
||
.. _constraints: | ||
|
||
=========== | ||
Constraints | ||
=========== | ||
|
||
Overview | ||
-------- | ||
|
||
Computation of the real-space axis positions given a set of reciprocal-space | ||
coordinates can have many solutions. One or more constraints | ||
(:class:`~hkl.util.Constraint`) (a.k.a, cut points), together with a choice of | ||
operating :ref:`mode <overview.mode>`, can be applied to: | ||
|
||
* limit the range of :ref:`constraints.forward` solutions accepted for that positioner | ||
* declare the value to use when the positioner should be kept constant | ||
|
||
Diffractometer constraints are described by: | ||
|
||
.. autosummary:: | ||
|
||
~hkl.util.Constraint | ||
|
||
These functions manage constraints: | ||
|
||
.. autosummary:: | ||
~hkl.diffract.Diffractometer.apply_constraints | ||
~hkl.diffract.Diffractometer.reset_constraints | ||
~hkl.diffract.Diffractometer.show_constraints | ||
~hkl.diffract.Diffractometer.undo_last_constraints | ||
~hkl.util.restore_constraints | ||
|
||
Diffractometer constraints can be exported and restored as part of a | ||
:class:`~hkl.configuration.DiffractometerConfiguration`: | ||
|
||
.. autosummary:: | ||
~hkl.configuration.DiffractometerConfiguration.export | ||
~hkl.configuration.DiffractometerConfiguration.restore | ||
|
||
.. this is coming in PR #299 | ||
~hkl.configuration.DiffractometerConfiguration.preview | ||
|
||
.. index:: cut points | ||
.. tip:: *Constraints* are implemented as *cut points* in other software. Similar yet not identical. | ||
|
||
Create a constraint | ||
------------------- | ||
|
||
A ``Constraint`` is defined as a :class:`~hkl.util.Constraint` object. For | ||
convenience, import directly from ``hkl.Constraint``:: | ||
|
||
hkl.Constraint(0, 90, 0, True) | ||
|
||
Consider a diffractometer object:: | ||
|
||
from hkl import SimulatedE4CV | ||
e4cv = SimulatedE4CV("", name="e4cv") | ||
|
||
The default constraints for this geometry are (using ``e4cv.show_constraints()``): | ||
|
||
===== ========= ========== ===== ==== | ||
axis low_limit high_limit value fit | ||
===== ========= ========== ===== ==== | ||
omega -180.0 180.0 0.0 True | ||
chi -180.0 180.0 0.0 True | ||
phi -180.0 180.0 0.0 True | ||
tth -180.0 180.0 0.0 True | ||
===== ========= ========== ===== ==== | ||
|
||
Apply the constraint | ||
-------------------- | ||
|
||
Apply a constraint *just* to the `"tth"` axis such that :math:`0<=2\theta<=120`:: | ||
|
||
e4cv.apply_constraints({"tth": Constraint(0, 120, 0, True)}) | ||
|
||
Show the constraints now (again, using ``e4cv.show_constraints()``): | ||
|
||
===== ========= ================== ===== ==== | ||
axis low_limit high_limit value fit | ||
===== ========= ================== ===== ==== | ||
omega -180.0 180.0 0.0 True | ||
chi -180.0 180.0 0.0 True | ||
phi -180.0 180.0 0.0 True | ||
tth 0.0 119.99999999999999 0.0 True | ||
===== ========= ================== ===== ==== | ||
|
||
Remove the constraint | ||
--------------------- | ||
|
||
Remove the previous constraint:: | ||
|
||
e4cv.undo_last_constraints() | ||
e4cv.show_constraints() | ||
|
||
Back to the defaults again: | ||
|
||
===== ========= ========== ===== ==== | ||
axis low_limit high_limit value fit | ||
===== ========= ========== ===== ==== | ||
omega -180.0 180.0 0.0 True | ||
chi -180.0 180.0 0.0 True | ||
phi -180.0 180.0 0.0 True | ||
tth -180.0 180.0 0.0 True | ||
===== ========= ========== ===== ==== | ||
|
||
Example | ||
------- | ||
|
||
Using the default sample (`main`), show the possible ``forward()`` solutions for | ||
a :math:`(100)` position with a :class:`hkl.geometries.E4CV` (4-circle) geometry | ||
diffractometer with these constraints: | ||
|
||
===== ========= ========== ===== ==== | ||
axis low_limit high_limit value fit | ||
===== ========= ========== ===== ==== | ||
omega 10.0 40.0 0.0 True | ||
chi -100.0 100.0 0.0 True | ||
phi -100.0 100.0 0.0 True | ||
tth 10.0 92.4 0.0 True | ||
===== ========= ========== ===== ==== | ||
|
||
First, make the diffractometer (simulator) and show the default constraints: | ||
|
||
.. code-block:: | ||
:linenos: | ||
|
||
from hkl import SimulatedE4CV | ||
|
||
e4cv = SimulatedE4CV("", name="e4cv") | ||
e4cv.show_constraints() | ||
|
||
===== ========= ========== ===== ==== | ||
axis low_limit high_limit value fit | ||
===== ========= ========== ===== ==== | ||
omega -180.0 180.0 0.0 True | ||
chi -180.0 180.0 0.0 True | ||
phi -180.0 180.0 0.0 True | ||
tth -180.0 180.0 0.0 True | ||
===== ========= ========== ===== ==== | ||
|
||
Make a convenience function to show all the possible :ref:`constraints.forward` | ||
solutions in a table. The complete list of possible solutions is provided by | ||
the low-level :meth:`~hkl.calc.CalcRecip.forward` method: | ||
|
||
.. code-block:: | ||
:linenos: | ||
|
||
import pyRestTable | ||
|
||
def all_forward_solutions(hkl_position): | ||
axes = e4cv.calc.physical_axis_names | ||
table = pyRestTable.Table() | ||
table.labels = axes | ||
for sol in e4cv.calc.forward(hkl_position): | ||
table.addRow([round(getattr(sol, k), 2) for k in axes]) | ||
print(f"solutions for forward({hkl_position}):") | ||
print(table) | ||
|
||
Show all solutions for the :math:`(100)` position (note the inner set of parentheses): | ||
|
||
.. code-block:: | ||
|
||
all_forward_solutions((1, 0, 0)) | ||
|
||
solutions for forward((1, 0, 0)): | ||
|
||
======= ===== ======= ====== | ||
omega chi phi tth | ||
======= ===== ======= ====== | ||
-30.21 0.0 -90.0 -60.42 | ||
30.21 0.0 90.0 60.42 | ||
-149.79 0.0 29.58 -60.42 | ||
-30.21 0.0 150.42 60.42 | ||
30.21 0.0 -150.42 -60.42 | ||
-149.79 0.0 -90.0 60.42 | ||
-30.21 180.0 90.0 -60.42 | ||
30.21 180.0 -90.0 60.42 | ||
-149.79 180.0 -29.58 -60.42 | ||
-30.21 180.0 -150.42 60.42 | ||
30.21 180.0 150.42 -60.42 | ||
-149.79 180.0 90.0 60.42 | ||
======= ===== ======= ====== | ||
|
||
Next, apply the new constraints and print the revised table: | ||
|
||
.. code-block:: | ||
:linenos: | ||
|
||
e4cv.apply_constraints( | ||
{ | ||
"omega": Constraint(10, 40, 0, True), | ||
"chi": Constraint(-100, 100, 0, True), | ||
"phi": Constraint(-100, 100, 0, True), | ||
"tth": Constraint(10, 92.4, 0, True), | ||
} | ||
) | ||
all_forward_solutions((1, 0, 0)) | ||
|
||
solutions for forward((1, 0, 0)): | ||
|
||
===== === ==== ===== | ||
omega chi phi tth | ||
===== === ==== ===== | ||
30.21 0.0 90.0 60.42 | ||
===== === ==== ===== | ||
|
||
Only one solution satisfies these constraints. | ||
|
||
.. _constraints.forward: | ||
|
||
``forward()`` | ||
------------- | ||
|
||
Given a set of reciprocal-space coordinates (typically :math:`h`, :math:`k`, and | ||
:math:`l`), compute the different sets of real-space coordinates which match. | ||
In the general case, the problem is over-determined. Multiple solutions are | ||
expected. These are the ``forward()`` computation methods: | ||
|
||
* :class:`~hkl.diffract.Diffractometer` . | ||
:meth:`~hkl.diffract.Diffractometer.forward` - provides one solution, if possible | ||
* (lower-level) :class:`~hkl.calc.CalcRecip` . | ||
:meth:`~hkl.calc.CalcRecip.forward` - provides a list of all *allowed* solutions | ||
|
||
The :meth:`hkl.diffract.Diffractometer.forward` method selects the first | ||
allowed solution from :meth:`hkl.calc.CalcRecip.forward`. This is the default | ||
choice as defined by :func:`hkl.calc.default_decision_function`. You can | ||
replace it with your own function. Then, either: | ||
|
||
* (easier) set your diffractometer object's | ||
:attr:`~hkl.diffract.Diffractometer._decision_fcn` attribute, such as: | ||
``e4cv._decision_fcn=your_function`` | ||
* (harder) pass it via the ``decision_fcn=your_function`` keyword when creating | ||
the :class:`~hkl.diffract.Diffractometer` object |
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The notebooks like this one are already rendered, which makes it hard to review as there are huge image diffs there. I think we can use https://github.com/kynan/nbstripout and auto-render the notebooks during the sphinx docs building process using https://nbsphinx.readthedocs.io/en/0.9.3/.