{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **hkl_soleil** UB matrix : calculate from 2 reflections.\n", "\n", "{math}`UB` is the 3x3 orientation matrix used to transform coordinates between\n", "reciprocal space directions (of the crystal lattice planes) and the rotational\n", "axes of the diffractometer." ] }, { "cell_type": "markdown", "id": "crossref-how-calc-ub", "metadata": {}, "source": [ "```{seealso}\n", "The how-to guide [How to Compute and Set the UB Matrix](../guides/how_calc_ub.rst) ", "covers the same workflow in prose form and includes additional patterns ", "such as setting UB directly and refining the lattice.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a diffractometer object\n", "\n", "First, create a diffractometer object that uses the `\"hkl_soleil\"` solver with\n", "the `\"hkl\"` computation engine. This solver provides support for many\n", "diffractometer geometries. This example will use the simulated 4-circle\n", "geometry from the solver's `\"E4CV\"`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import hklpy2\n", "\n", "diffractometer = hklpy2.creator(name=\"diffractometer\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Defaults\n", "\n", "The diffractometer object starts with a default sample. The structure is cubic ({math}`a=b=c`, 90 degree corners)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sample(name='sample', lattice=Lattice(a=1, system='cubic'))" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.sample" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add 2 reflections\n", "\n", "Two reflections are needed to calculate $UB$. Since we do not specify the wavelength, the support assumes the diffractometer's current wavelength." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.beam.wavelength.get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add two non-parallel reflections. The motor positions are specified\n", "as a dictionary of named real-axis values, making the example readable\n", "regardless of the solver's internal axis order." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "r100 = diffractometer.add_reflection(\n", " (1, 0, 0),\n", " dict(omega=-145.451, chi=5, phi=-5, tth=69.0966),\n", " name=\"(100)\",\n", ")\n", "r010 = diffractometer.add_reflection(\n", " (0, 1, 0),\n", " dict(omega=-145.451, chi=5, phi=85, tth=69.0966),\n", " name=\"(010)\",\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Compute UB\n", "\n", "Compute $UB$ with these two reflections:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[0.545455242664, -6.239788247453, -0.49592954663],\n", " [-0.547615556651, -0.543471893498, 6.235636483453],\n", " [-6.235462715682, -0.498106806877, -0.591013170474]]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.core.calc_UB(r100, r010)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show the calculated $UB$ matrix:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[0.545455242664, -6.239788247453, -0.49592954663],\n", " [-0.547615556651, -0.543471893498, 6.235636483453],\n", " [-6.235462715682, -0.498106806877, -0.591013170474]]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.sample.UB" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Try it out\n", "\n", " corresponding to the $(1,0,0)$ reflection:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Hklpy2DiffractometerRealPos(omega=-150.000007544679, chi=4.999999954605, phi=-4.999297290893, tth=59.999984910642)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.forward(1, 0, 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show the (first set of computed) angles corresponding to the $(1 \\bar1 1)$ reflection:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Hklpy2DiffractometerRealPos(omega=-120.000010463815, chi=-34.931759528333, phi=-44.822654658067, tth=119.99997907237)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffractometer.forward(1, -1, 1)" ] } ], "metadata": { "kernelspec": { "display_name": "hklpy2", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.11" } }, "nbformat": 4, "nbformat_minor": 2 }