pyextal.jaxGeo.refine ===================== .. py:module:: pyextal.jaxGeo.refine .. autoapi-nested-parse:: The refinement: Adam in segments, the geometry refined between them. Adam runs on the structure factors, thickness, scale, background and probe. Every ``geo_every`` steps from ``geo_start`` it stops, and the geometry (``gl``, ``rotation``, ``tiltx``, ``tilty``) is refined by Levenberg-Marquardt on exact JAX derivatives of the loss with everything else held fixed (`jaxGeo.lm`, `jaxGeo.objective`, `jaxGeo.geometry`). Adam's state carries across segments, so releasing the geometry does not reset the momentum on the structure factors. Before anything is refined, two checks must pass: the affine geometry model must reproduce the exported tilt grid, and the JAX excitation errors must reproduce the engine's. Either failing means the derivatives would be of the wrong function, and the run stops. Complex structure factors (``imag``) ------------------------------------ ``imag='none'`` refines the real parts of U_g and U'_g only, which is exact for a centrosymmetric group with its inversion centre on the origin. ``'elastic'`` frees Im U_g and ``'both'`` Im U'_g as well, so each refined U_g has an amplitude and a continuous phase. That forces three things: * **Friedel symmetry, not the space group.** Under ``SpaceGroup`` a centrosymmetric group makes the engine fill U(-g) with the *same* complex value as U(g) -- inversion for real U_g, a non-Hermitian potential once Im U_g is free. ``Friedel`` pairs U(-g) = U(g)* instead -- Hermitian, and true for any crystal -- and drops the space-group ties, so each (g, -g) pair is one complex parameter and its equivalents off the zone stay at their tabulated values. ``symmetry`` defaults to Friedel whenever ``imag`` is not ``'none'``. * **Both of g and -g are named** (`jaxGeo.reflections.friedel_reflections`), so the engine's label for the pair is always among the requested reflections. * **The origin is not free.** A complex U_g on its own is defined only up to an origin shift, U_g -> U_g exp(2 pi i g.r0). Every reflection not refined stays real at its tabulated value, which pins the origin; the refined phases are relative to that reference. Imaginary parts start at zero. Their gradient there is not zero when the data break the centrosymmetry: to first order it measures exactly the difference between a pair's rocking curves that a real U_g cannot produce. A caution: an asymmetric (g, -g) pair on zone is also what a residual tilt, a thickness gradient or a mis-set rotation produces -- check that the geometry has converged and that the real-only run cannot fit the pair before attributing a phase to the structure. The run ends with a table of amplitude and phase. A specimen in layers (``layers``) --------------------------------- With ``layers=N`` the specimen is N slabs stacked along the beam, entrance surface first, each with its own thickness and its own copy of every refined structure factor; the wave is propagated through them in turn. Reflections not refined are the same tabulated values in every layer. It is for a crystal whose structure is not uniform through its thickness -- a damaged or reconstructed surface layer, a strain or composition gradient, a second domain. A uniform crystal makes the layers redundant: they drift to the same U_g, or one shrinks towards zero thickness. ``layer_fractions`` shares the starting thickness between the layers (default equal); each layer's thickness then refines independently. ``refine_layers`` (1-based) chooses whose structure factors are free -- e.g. ``2`` holds layer 1 at the tabulated (bulk) values. Identical layers that start identical and are all free can trade structure factors almost freely, so holding the bulk layer or starting from unequal fractions breaks that symmetry. The run ends with a per-layer table and ``
__layers.png``. Over-subtracted reflections (``oversub``) ----------------------------------------- See `jaxGeo.oversub`: listed reflections are compared as ``max(sim - c - k * I(000), 0)``, with ``c`` and ``k`` fitted at ``oversub_start`` and then released to Adam. Functions --------- .. autoapisummary:: pyextal.jaxGeo.refine._select_cpu pyextal.jaxGeo.refine.refine Module Contents --------------- .. py:function:: _select_cpu() Forces the CPU backend, before or after JAX has been imported. .. py:function:: refine(settings=None, **overrides) Runs a refinement, or validates its setup with ``dry_run``. :param settings: The options. :type settings: RefineSettings, optional :param \*\*overrides: Fields to change on ``settings`` (or on the defaults). :returns: ``config``, ``params``, ``metadata``, ``constants``, ``geometry`` (the refined geometry dict) and, unless ``dry_run``, ``run`` (the run key written to the file, or None if the simulation failed), ``loss_history`` and ``geometry_history``. :rtype: dict :raises SetupError: If the dataset, the ``.dat`` or the options are unusable.