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

add APS POLAR geometry #338

Merged
merged 18 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions docs/make_geometry_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@

.. _geometry_tables:

=================================
=========================
Diffractometer Geometries
=================================
=========================

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.
.. index:: mode

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 :ref:`mode <overview.mode>`. The mode
defines which axes will be computed, which will be held constant, and any
relationships between axes.

Geometries indexed by number of circles
---------------------------------------
Expand Down
51 changes: 33 additions & 18 deletions docs/source/diffract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,46 @@ capabilities are also customized in a local subclass.
Examples are provided in the
:ref:`Geometries Examples <geometries.examples>` section.

.. _diffract.geometries.common:

Common Diffractometer Geometries
++++++++++++++++++++++++++++++++

These are the diffractometer geometries provided by the **libhkl**
library [#libhkl]_:

============================== ==========================
name description
============================== ==========================
:class:`~hkl.geometries.E4CH` Eulerian 4-circle, vertical scattering plane
:class:`~hkl.geometries.E4CV` Eulerian 4-circle, horizontal scattering plane
:class:`~hkl.geometries.E6C` Eulerian 6-circle
:class:`~hkl.geometries.K4CV` Kappa 4-circle, vertical scattering plane
:class:`~hkl.geometries.K6C` Kappa 6-circle
:class:`~hkl.geometries.Zaxis` Z-axis
============================== ==========================
.. autosummary::
:nosignatures:

~hkl.geometries.E4CH
~hkl.geometries.E4CV
~hkl.geometries.E6C
~hkl.geometries.K4CV
~hkl.geometries.K6C
~hkl.geometries.Zaxis

.. _diffract.geometries.special_use:

Special-use Diffractometer Geometries
+++++++++++++++++++++++++++++++++++++

These special-use geometries are also provided by the **libhkl**
library [#libhkl]_:

* :class:`~hkl.geometries.Petra3_p09_eh2`
* :class:`~hkl.geometries.SoleilMars`
* :class:`~hkl.geometries.SoleilSiriusKappa`
* :class:`~hkl.geometries.SoleilSiriusTurret`
* :class:`~hkl.geometries.SoleilSixsMed1p2`
* :class:`~hkl.geometries.SoleilSixsMed2p2`
* :class:`~hkl.geometries.SoleilSixsMed2p3`
* :class:`~hkl.geometries.SoleilSixsMed2p3v2`
.. autosummary::
:nosignatures:

~hkl.geometries.ApsPolar
~hkl.geometries.Petra3_p09_eh2
~hkl.geometries.Petra3_p23_4c
~hkl.geometries.Petra3_p23_6c
~hkl.geometries.SoleilMars
~hkl.geometries.SoleilSiriusKappa
~hkl.geometries.SoleilSiriusTurret
~hkl.geometries.SoleilSixsMed1p2
~hkl.geometries.SoleilSixsMed2p2
~hkl.geometries.SoleilSixsMed2p3
~hkl.geometries.SoleilSixsMed2p3v2

In all cases, see the **libhkl** documentation for further information
on these geometries.
Expand Down
38 changes: 33 additions & 5 deletions docs/source/geometry_tables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Diffractometer Geometries

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 :ref:`mode <overview.mode>`. The mode defines
which axes will be computed, which will be held constant, and any relationships
between axes.
additional parameters required by the :ref:`mode <overview.mode>`. The mode
defines which axes will be computed, which will be held constant, and any
relationships between axes.

Geometries indexed by number of circles
---------------------------------------
Expand All @@ -37,6 +37,7 @@ used here in |hklpy|).
4 :ref:`ZAXIS <ZAXIS_table>` ``mu``, ``omega``, ``delta``, ``gamma``
5 :ref:`SOLEIL SIXS MED2+2 <SOLEIL_SIXS_MED2+2_table>` ``beta``, ``mu``, ``omega``, ``gamma``, ``delta``
5 :ref:`SOLEIL SIXS MED2+3 v2 <SOLEIL_SIXS_MED2+3_v2_table>` ``mu``, ``omega``, ``gamma``, ``delta``, ``eta_a``
6 :ref:`APS POLAR <APS_POLAR_table>` ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta``
6 :ref:`E6C <E6C_table>` ``mu``, ``omega``, ``chi``, ``phi``, ``gamma``, ``delta``
6 :ref:`K6C <K6C_table>` ``mu``, ``komega``, ``kappa``, ``kphi``, ``gamma``, ``delta``
6 :ref:`PETRA3 P09 EH2 <PETRA3_P09_EH2_table>` ``mu``, ``omega``, ``chi``, ``phi``, ``delta``, ``gamma``
Expand All @@ -54,8 +55,6 @@ used here in |hklpy|).
Tables for each geometry
------------------------

.. index:: mode

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.
Expand All @@ -71,6 +70,35 @@ required by the mode.
* *axes written* : Axes computed by the ``forward()`` computation.
* *extra parameters* : Any necessary additional parameters.

.. index:: APS_POLAR, geometry; APS_POLAR

.. _APS_POLAR_table:

Geometry: ``APS POLAR``
+++++++++++++++++++++++

* real axes: ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta``
* pseudo axes: depends on the engine

====== =================== ================================= ======================================================= ===================================== ===============================
engine pseudo axes mode axes read axes written extra parameters
====== =================== ================================= ======================================================= ===================================== ===============================
hkl ``h``, ``k``, ``l`` 4-circles bissecting horizontal ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``chi``, ``phi``, ``gamma``
hkl ``h``, ``k``, ``l`` 4-circles constant chi horizontal ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``phi``, ``gamma``
hkl ``h``, ``k``, ``l`` 4-circles constant mu horizontal ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``chi``, ``phi``, ``gamma``
hkl ``h``, ``k``, ``l`` 4-circles constant phi horizontal ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``chi``, ``gamma``
hkl ``h``, ``k``, ``l`` lifting detector chi ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``chi``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` lifting detector mu ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``tau``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` lifting detector mu ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``tau``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` lifting detector phi ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``phi``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` psi constant horizontal ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``chi``, ``phi``, ``gamma`` ``h2``, ``k2``, ``l2``, ``psi``
hkl ``h``, ``k``, ``l`` psi constant vertical ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``tau``, ``chi``, ``phi``, ``delta`` ``h2``, ``k2``, ``l2``, ``psi``
hkl ``h``, ``k``, ``l`` zaxis + alpha-fixed ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` zaxis + alpha=beta ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``tau``, ``mu``, ``gamma``, ``delta``
hkl ``h``, ``k``, ``l`` zaxis + beta-fixed ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``tau``, ``gamma``, ``delta``
psi ``psi`` psi_vertical ``tau``, ``mu``, ``chi``, ``phi``, ``gamma``, ``delta`` ``mu``, ``chi``, ``phi``, ``delta`` ``h2``, ``k2``, ``l2``
====== =================== ================================= ======================================================= ===================================== ===============================

.. index:: E4CH, geometry; E4CH

.. _E4CH_table:
Expand Down
5 changes: 3 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ dependencies:
- python >=3.8,<3.12
- apischema
- bluesky
- databroker
- databroker <=1.999
- hkl
- numpy
- numpy <=1.999
Comment on lines +18 to +20
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not <2 ?

- ophyd
- orjson
- packaging
- pint
- pip
Expand Down
1 change: 1 addition & 0 deletions hkl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from .geometries import E6C
from .geometries import K4CV
from .geometries import K6C
from .geometries import ApsPolar
from .geometries import Petra3_p09_eh2
from .geometries import Petra3_p23_4c
from .geometries import Petra3_p23_6c
Expand Down
9 changes: 9 additions & 0 deletions hkl/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

.. autosummary::

~CalcApsPolar
~CalcE4CH
~CalcE4CV
~CalcE6C
Expand Down Expand Up @@ -47,6 +48,7 @@

__all__ = """
A_KEV
CalcApsPolar
CalcE4CH
CalcE4CV
CalcE6C
Expand Down Expand Up @@ -806,6 +808,13 @@ def _cfg_reciprocal(self):
return tuple(list(self.sample.reciprocal))


class CalcApsPolar(CalcRecip):
"""Geometry: APS POLAR"""

def __init__(self, **kwargs):
super().__init__("APS POLAR", **kwargs)


class CalcE4CH(CalcRecip):
"""Geometry: E4CH"""

Expand Down
2 changes: 1 addition & 1 deletion hkl/diffract.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

"""


import logging

import pint
Expand Down Expand Up @@ -113,6 +112,7 @@ class (using `calc_kw`) to instantiate a new one.

See Also
--------
:class:`~hkl.geometries.ApsPolar
:class:`~hkl.geometries.E4CH`
:class:`~hkl.geometries.E4CV`
:class:`~hkl.geometries.E6C`
Expand Down
8 changes: 8 additions & 0 deletions hkl/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

.. autosummary::

~ApsPolar
~Petra3_p09_eh2
~Petra3_p23_4c
~Petra3_p23_6c
Expand All @@ -54,6 +55,7 @@
from .diffract import Diffractometer

__all__ = """
ApsPolar
E4CH
E4CV
E6C
Expand All @@ -80,6 +82,12 @@
logger = logging.getLogger(__name__)


class ApsPolar(Diffractometer):
"""APS POLAR 6-circle diffractometer."""

calc_class = calc.CalcApsPolar


class E4CH(Diffractometer):
"""Eulerian 4-circle, horizontal scattering plane"""

Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_diffract.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


@pytest.fixture(scope="function")
Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_extra_motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


FOURC_SETUP_CODE = """
Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_fourc.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


def check_hkl(diffractometer, h, k, l):
Expand Down
1 change: 1 addition & 0 deletions hkl/tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
[
("calc", "A_KEV"),
("calc", "UnreachableError"),
("geometries", "ApsPolar"),
("geometries", "E4CH"),
("geometries", "E4CV"),
("geometries", "E6C"),
Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


@pytest.fixture(scope="function")
Expand Down
4 changes: 2 additions & 2 deletions hkl/tests/test_save_restore_UB.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


class Kappa(SimulatedK4CV):
...
"""Kappa 4-circle for testing."""


@pytest.fixture
Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class Fourc(SimulatedE4CV):
...
"""4-circle for testing."""


@pytest.fixture(scope="function")
Expand Down
2 changes: 1 addition & 1 deletion hkl/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from bluesky import plans as bp
from bluesky.run_engine import RunEngine
from packaging import version
from tiled.utils import safe_json_dump

from .. import util
from .tools import DocsCollector
from .tools import safe_json_dump
from .tools import validate_descriptor_doc_content

NO_SUCH_PACKAGE_NAME = "no-such-package"
Expand Down
37 changes: 36 additions & 1 deletion hkl/tests/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from pathlib import Path # noqa

import numpy
from tiled.utils import safe_json_dump

from ..util import new_lattice

Expand Down Expand Up @@ -90,3 +89,39 @@ def validate_descriptor_doc_content(gname, descriptor):
]
for attr, struct in attrs:
assert isinstance(data.get(f"{gname}_{attr}"), struct), f"{attr=!r} {list(data)=!r}"


def safe_json_dump(content):
"""
Vendored from tiled.utils

https://github.com/bluesky/tiled/blob/15abbc98df9bfd25f8c713656f664a558136e26f/tiled/utils.py#L526

Base64-encode raw bytes, and provide a fallback if orjson numpy handling fails.
"""
import base64
import sys

import orjson

def default(content):
if isinstance(content, bytes):
content = f"data:application/octet-stream;base64,{base64.b64encode(content).decode('utf-8')}"
return content
if isinstance(content, Path):
return str(content)
# No need to import numpy if it hasn't been used already.
numpy = sys.modules.get("numpy", None)
if numpy is not None:
if isinstance(content, numpy.ndarray):
# If we make it here, OPT_NUMPY_SERIALIZE failed because we have hit some edge case.
# Give up on the numpy fast-path and convert to Python list.
# If the items in this list aren't serializable (e.g. bytes) we'll recurse on each item.
return content.tolist()
elif isinstance(content, (bytes, numpy.bytes_)):
return content.decode("utf-8")
raise TypeError

# Not all numpy dtypes are supported by orjson.
# Fall back to converting to a (possibly nested) Python list.
return orjson.dumps(content, option=orjson.OPT_SERIALIZE_NUMPY, default=default)
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ docs = [
]
tests = [
"bluesky",
"tiled",
"databroker <=1.999",
"numpy <=1.999",
Comment on lines +68 to +69
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not <2 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In Python version comparisons: 2.0.0b46 < 2, we need to be below anything with a 2 in the major position, even pre-releases such as 2.0.0b46.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh, pre-releases. I thought that would not be used without explicitly requesting --allow-prerelease.

I suppose it comes by default because 2.0 is only available as a pre-release. That behavior will presumably go away when 2.0 gets released.

Copy link
Contributor Author

@prjemian prjemian Aug 7, 2024

Choose a reason for hiding this comment

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

It's on conda-forge. Might be that pip respects pre-releases. Certainly, conda has stepped firmly into that pothole.

"orjson",
"packaging",
]
all = ["hklpy[docs,tests]"]
Expand Down