Skip to content
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

Describe geometry engines, modes, and axes #306

Merged
merged 12 commits into from
Dec 15, 2023
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ docs/source/generated
# Microsoft VS Code editor
.vscode/
.history/
docs/source/_build/

# PyTest cache
.pytest_cache/
Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ New Features and/or Enhancements
* Export and restore diffractometer configuration as JSON string, YAML string, Python dictionary, or file.
* Add ``user.current_diffractometer()`` function.
* Add ``axes_r``, ``axes_w``, & ``axes_c`` properties to both ``calc`` & ``engine``.
* Build tables of diffractometer geometry, engines, and modes from *libhkl* API.
* Export and reload diffractometer configuration as JSON string, YAML string, or Python dictionary.

Fixes
Expand Down
117 changes: 117 additions & 0 deletions docs/make_geometry_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"""
(Re)create the geometry_tables.rst document.

Run this manually, as needed::
prjemian marked this conversation as resolved.
Show resolved Hide resolved

python \
./docs/make_geometry_tables.py \
| tee ./docs/source/geometry_tables.rst

"""

import sys

import pyRestTable

from hkl import calc

PAGE_HEAD = f"""
.. this page created by {sys.argv[0]}

.. _geometry_tables:

=================================
Tables of Diffractometer Geometry
=================================

Tables are provided for the different geometries and then, for each
geometry, the calculation engines, pseudo axes required, modes of
operation, and any additional parameters required by the mode.

Geometries indexed by number of circles
---------------------------------------

The different diffractometer geometries are distinguished, primarily, by
the number of axes (circles) and the names of each. This table is
sorted first by the number of circles, and then the geometry name (as
used here in *hklpy*).

"""

TABLES_HEAD = """

.. _geometry_tables.tables:

Tables for each geometry
------------------------

A table is provided for each diffractometer geometry listing the calculation
engines, pseudo axes required, modes of operation, and any additional parameters
required by the mode.

* *engine* : Defines the names (and order) of the pseudo axes.
* *pseudo axes* : The engine performs
:meth:`~hkl.diffract.Diffractometer.forward()` (pseudo-to-real) and
:meth:`~hkl.diffract.Diffractometer.inverse()` (real-to-pseudo)
transformations between the real-space axes and the *pseudo* (typically
reciprocal-space) axes. The *engine* defines the *pseudo axes* to be used.
* *mode* : Defines which axes are used for the ``forward()`` computation.
* *axes read* : Axes used in the ``forward()`` computation.
* *axes written* : Axes computed by the ``forward()`` computation.
* *extra parameters* : Any necessary additional parameters.
"""


def goniometers():
for cname in dir(calc):
if cname.startswith("Calc"):
try:
yield getattr(calc, cname)()
except TypeError:
pass


def print_summary_table():
def format_name_list(names):
names = [f"``{k}``" for k in names]
return ", ".join(names)

db = {
gonio.geometry_name: {
"real_axes": gonio.physical_axis_names,
"cname": gonio.__class__.__name__[4:], # 4 = len("Calc") as in "CalcE4CV"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"cname": gonio.__class__.__name__[4:], # 4 = len("Calc") as in "CalcE4CV"
"cname": gonio.__class__.__name__[len("Calc"):],

}
for gonio in goniometers()
}

def sorter(gname):
return f"{len(db[gname]['real_axes'])}-{gname}"

table = pyRestTable.Table()
table.addLabel("#circles")
table.addLabel("geometry")
table.addLabel("real_axes")
for gname in sorted(db.keys(), key=sorter):
gname_safe = gname.replace(" ", "_")
entry = db[gname]
real_axes = entry["real_axes"]
table.addRow(
[
len(real_axes),
f":ref:`{gname} <{gname_safe}_table>`",
format_name_list(real_axes),
]
)
print(table)


def print_geometry_tables(rst=True):
for gonio in goniometers():
gonio.geometry_table(rst=rst)


if __name__ == "__main__":
print(PAGE_HEAD.lstrip())
print_summary_table()
print(TABLES_HEAD)
print_geometry_tables(rst=True)
1 change: 1 addition & 0 deletions docs/source/calc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ Module: ``calc``

.. automodule:: hkl.calc
:members:
:undoc-members:
Loading
Loading