.. _concepts.solvers: ================== Solvers ================== .. TODO: How much is guide or example? This should be a concepts doc. Brief. .. TODO: - Describe the responsibilities of a |solver|. - Define the terms expected (add to glossary.). - Note that solvers provide different features: additions and not availables .. index:: !design; solver A |solver| is a Python class that connects |hklpy2| with a (backend) library that provides diffractometer capabilities, including: * definition(s) of physical diffractometer **geometries** * axes (angles and reciprocal space) * operating **modes** for the axes (angles and reciprocal space) * calculations that convert: * **forward**: reciprocal space coordinates into diffractometer angles * **inverse**: diffractometer angles into reciprocal space coordinates * support blocks include: * calculate the UB matrix * refine the crystal lattice * sample definition * name * crystal lattice parameters: :math:`a, b, c, \alpha, \beta, \gamma` * list of orientation reflections .. index:: entry point A |solver| class is written as a plugin for |hklpy2| and is connected by an `entry point <https://setuptools.pypa.io/en/latest/userguide/entry_point.html#entry-points-for-plugins>`_ using the ``"hklpy2.solver"`` group. Here's an example from |hklpy2|'s ``pyproject.toml`` file for two such |solver| classes:: [project.entry-points."hklpy2.solver"] hkl_soleil = "hklpy2.backends.hkl_soleil:HklSolver" th_tth = "hklpy2.backends.th_tth_q:ThTthSolver" .. _api.solvers.set: How to select a Solver ---------------------- To list all available |solver| classes (by their entry point name), call :func:`~hklpy2.backends.base.solvers()`. This example shows the |solver| classes supplied with |hklpy2|:: >>> from hklpy2 import solvers >>> solvers() {'hkl_soleil': 'hklpy2.backends.hkl_soleil:HklSolver', 'th_tth': 'hklpy2.backends.th_tth_q:ThTthSolver'} This is a dictionary, keyed by the solver names. To create an instance of a specific |solver| class, use :func:`~hklpy2.misc.solver_factory`. In the next example (Linux-only), the first argument, `hkl_soleil`, picks the :class:`~hklpy2.backends.hkl_soleil.HklSolver`, the `geometry` keyword picks the Eulerian 4-circle geometry with the *hkl* engine: .. code-block: Python :linenos: >>> from hklpy2 import solver_factory >>> solver = solver_factory("hkl_soleil", "E4CV") >>> print(solver) HklSolver(name='hkl_soleil', version='v5.0.0.3434', geometry='E4CV', engine='hkl') To select a |solver| class without creating an instance, call :func:`~hklpy2.misc.get_solver`. This example selects the |libhkl| |solver| (using its entry point name: ``"hkl_soleil"``): .. code-block: Python :linenos: >>> from hklpy2 import get_solver >>> Solver = get_solver("hkl_soleil") >>> print(f"{Solver=}") Solver=<class 'hklpy2.backends.hkl_soleil.HklSolver'> Solver: hkl_soleil ~~~~~~~~~~~~~~~~~~~~~~ *Hkl* (`documentation <https://people.debian.org/~picca/hkl/hkl.html>`_), from Synchrotron Soleil, is used as a backend library to convert between real-space motor coordinates and reciprocal-space crystallographic coordinates. Here, we refer to this library as **hkl_soleil** to clarify and distinguish from other use of of the term *hkl*. Multiple source code repositories exist. |hklpy2| uses the `active development repository <https://repo.or.cz/hkl.git>`_. .. caution:: At this time, it is only compiled for 64-bit Linux. Not Windows, not Mac OS. Solver: no_op ~~~~~~~~~~~~~~~~~~~~~~ This solver was built for testing the |hklpy2| code. It provides no useful geometries for diffractometer users. Solver: th_tth ~~~~~~~~~~~~~~~~~~~~~~ This solver was built as a demonstration of a minimal all Python solver. It provides basic support for $\theta, 2\theta$ geometry with a $Q$ pseudo axis. It can be used on any OS where Python runs. How to write a Solver ---------------------- .. seealso:: :ref:`howto.solvers.write`