{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Diffractometer Configuration -- Save and Restore\n", "\n", "This document shows examples that save and restore the configuration details of\n", "a diffractometer. The configuration can be saved to a [file](#files). Also,\n", "the configuration can be saved in a bluesky [run](#run) (with the run's\n", "metadata). The details include:\n", "\n", "- diffractometer name\n", "- axes\n", " - real-space axis names\n", " - mapping to canonical real-space axes known to the solver\n", " - reciprocal-space axis names\n", " - any extra axes, as used by the solver\n", "- sample(s)\n", " - lattice\n", " - orientation\n", " - reflections\n", "- constraints\n", "- solver\n", " - geometry\n", " - real-space axes\n", " - mode\n", " - version\n", "- _header (date & time, energy, wavelength, source type, version)\n", "\n", "With these configuration details, it should be possible to recover a\n", "diffractometer orientation from a previous run or from file storage." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Files\n", "\n", "Create a simulated 4-circle diffractometer. Use the factory function. The\n", "default will use the E4CV geometry from the hkl_soleil solver." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import hklpy2\n", "\n", "sim4c = hklpy2.creator(name=\"sim4c\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add a *vibranium* sample and describe its orientation." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Reflection(name='r1', h=1, k=0, l=0)\n", "Reflection(name='r2', h=0, k=1, l=0)\n" ] }, { "data": { "text/plain": [ "[[-0.0, -0.0, 1.0], [0.0, -1.0, 0.0], [1.0, -0.0, -0.0]]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import math\n", "\n", "sim4c.add_sample(\"vibranium\", 2*math.pi, digits=3)\n", "sim4c.add_reflection((1, 0, 0), (10, 0, 0, 20), name=\"r1\")\n", "sim4c.add_reflection((0, 1, 0), (10, -90, 0, 20), name=\"r2\")\n", "for r in sim4c.sample.reflections.order:\n", " print(f\"{sim4c.sample.reflections[r]}\")\n", "sim4c.core.calc_UB(*sim4c.sample.reflections.order)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show details about the diffractometer configuration:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'_header': {'datetime': '2025-03-26 12:38:33.168087',\n", " 'hklpy2_version': '0.0.28.dev92+g12cedce.d20250326',\n", " 'python_class': 'Hklpy2Diffractometer',\n", " 'source_type': 'X-ray',\n", " 'energy_units': 'keV',\n", " 'energy': 12.398419843856837,\n", " 'wavelength_units': 'angstrom',\n", " 'wavelength': 1.0},\n", " 'name': 'sim4c',\n", " 'axes': {'pseudo_axes': ['h', 'k', 'l'],\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'axes_xref': {'h': 'h',\n", " 'k': 'k',\n", " 'l': 'l',\n", " 'omega': 'omega',\n", " 'chi': 'chi',\n", " 'phi': 'phi',\n", " 'tth': 'tth'},\n", " 'extra_axes': {}},\n", " 'sample_name': 'vibranium',\n", " 'samples': {'sample': {'name': 'sample',\n", " 'lattice': {'a': 1,\n", " 'b': 1,\n", " 'c': 1,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {},\n", " 'reflections_order': [],\n", " 'U': [[1, 0, 0], [0, 1, 0], [0, 0, 1]],\n", " 'UB': [[6.283185307179586, 0.0, 0.0],\n", " [0.0, 6.283185307179586, 0.0],\n", " [0.0, 0.0, 6.283185307179586]],\n", " 'digits': 4},\n", " 'vibranium': {'name': 'vibranium',\n", " 'lattice': {'a': 6.283185307179586,\n", " 'b': 6.283185307179586,\n", " 'c': 6.283185307179586,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {'r1': {'name': 'r1',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 1, 'k': 0, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': 0, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4},\n", " 'r2': {'name': 'r2',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 0, 'k': 1, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': -90, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4}},\n", " 'reflections_order': ['r1', 'r2'],\n", " 'U': [[-0.0, -0.0, 1.0], [0.0, -1.0, -0.0], [1.0, -0.0, 0.0]],\n", " 'UB': [[-0.0, -0.0, 1.0], [0.0, -1.0, 0.0], [1.0, -0.0, -0.0]],\n", " 'digits': 3}},\n", " 'constraints': {'omega': {'label': 'omega',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'chi': {'label': 'chi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'phi': {'label': 'phi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'tth': {'label': 'tth',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'}},\n", " 'solver': {'name': 'hkl_soleil',\n", " 'description': \"HklSolver(name='hkl_soleil', version='5.1.2', geometry='E4CV', engine_name='hkl', mode='bissector')\",\n", " 'geometry': 'E4CV',\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'version': '5.1.2',\n", " 'engine': 'hkl'}}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c.configuration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Export (save) the configuration\n", "\n", "Save the `sim4c` configuration (with vibranium sample orientation) to a\n", "[YAML](https://yaml.org) file in the current working directory:\n", "`dev_e4cv-vibranium.yml`. (Here, we choose to identify file by including the\n", "diffractometer geometry as part of the file name. The `dev_` prefix is an\n", "additional arbitrary choice, you could choose a completely different file name.)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "sim4c.export(\"dev_e4cv-vibranium.yml\", comment=\"example\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's look at that file. Then, compare it with the `sim4c.configuration`\n", "reported above." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[38;5;66;03m#hklpy2 configuration file\u001b[39;00m\n", "\n", "_header:\n", " datetime: \u001b[33m'2025-03-26 12:38:33.327299'\u001b[39m\n", " hklpy2_version: \u001b[32m0.0\u001b[39m\u001b[32m.28\u001b[39m.dev92+g12cedce.d20250326\n", " python_class: Hklpy2Diffractometer\n", " source_type: X-ray\n", " energy_units: keV\n", " energy: \u001b[32m12.398419843856837\u001b[39m\n", " wavelength_units: angstrom\n", " wavelength: \u001b[32m1.0\u001b[39m\n", " file: dev_e4cv-vibranium.yml\n", " comment: example\n", "name: sim4c\n", "axes:\n", " pseudo_axes:\n", " - h\n", " - k\n", " - l\n", " real_axes:\n", " - omega\n", " - chi\n", " - phi\n", " - tth\n", " axes_xref:\n", " h: h\n", " k: k\n", " l: l\n", " omega: omega\n", " chi: chi\n", " phi: phi\n", " tth: tth\n", " extra_axes: {}\n", "sample_name: vibranium\n", "samples:\n", " sample:\n", " name: sample\n", " lattice:\n", " a: \u001b[32m1\u001b[39m\n", " b: \u001b[32m1\u001b[39m\n", " c: \u001b[32m1\u001b[39m\n", " alpha: \u001b[32m90.0\u001b[39m\n", " beta: \u001b[32m90.0\u001b[39m\n", " gamma: \u001b[32m90.0\u001b[39m\n", " reflections: {}\n", " reflections_order: []\n", " U:\n", " - - \u001b[32m1\u001b[39m\n", " - \u001b[32m0\u001b[39m\n", " - \u001b[32m0\u001b[39m\n", " - - \u001b[32m0\u001b[39m\n", " - \u001b[32m1\u001b[39m\n", " - \u001b[32m0\u001b[39m\n", " - - \u001b[32m0\u001b[39m\n", " - \u001b[32m0\u001b[39m\n", " - \u001b[32m1\u001b[39m\n", " UB:\n", " - - \u001b[32m6.283185307179586\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " - - \u001b[32m0.0\u001b[39m\n", " - \u001b[32m6.283185307179586\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " - - \u001b[32m0.0\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " - \u001b[32m6.283185307179586\u001b[39m\n", " digits: \u001b[32m4\u001b[39m\n", " vibranium:\n", " name: vibranium\n", " lattice:\n", " a: \u001b[32m6.283185307179586\u001b[39m\n", " b: \u001b[32m6.283185307179586\u001b[39m\n", " c: \u001b[32m6.283185307179586\u001b[39m\n", " alpha: \u001b[32m90.0\u001b[39m\n", " beta: \u001b[32m90.0\u001b[39m\n", " gamma: \u001b[32m90.0\u001b[39m\n", " reflections:\n", " r1:\n", " name: r1\n", " geometry: E4CV\n", " pseudos:\n", " h: \u001b[32m1\u001b[39m\n", " k: \u001b[32m0\u001b[39m\n", " l: \u001b[32m0\u001b[39m\n", " reals:\n", " omega: \u001b[32m10\u001b[39m\n", " chi: \u001b[32m0\u001b[39m\n", " phi: \u001b[32m0\u001b[39m\n", " tth: \u001b[32m20\u001b[39m\n", " wavelength: \u001b[32m1.0\u001b[39m\n", " digits: \u001b[32m4\u001b[39m\n", " r2:\n", " name: r2\n", " geometry: E4CV\n", " pseudos:\n", " h: \u001b[32m0\u001b[39m\n", " k: \u001b[32m1\u001b[39m\n", " l: \u001b[32m0\u001b[39m\n", " reals:\n", " omega: \u001b[32m10\u001b[39m\n", " chi: -\u001b[32m90\u001b[39m\n", " phi: \u001b[32m0\u001b[39m\n", " tth: \u001b[32m20\u001b[39m\n", " wavelength: \u001b[32m1.0\u001b[39m\n", " digits: \u001b[32m4\u001b[39m\n", " reflections_order:\n", " - r1\n", " - r2\n", " U:\n", " - - -\u001b[32m0.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " - \u001b[32m1.0\u001b[39m\n", " - - \u001b[32m0.0\u001b[39m\n", " - -\u001b[32m1.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " - - \u001b[32m1.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " UB:\n", " - - -\u001b[32m0.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " - \u001b[32m1.0\u001b[39m\n", " - - \u001b[32m0.0\u001b[39m\n", " - -\u001b[32m1.0\u001b[39m\n", " - \u001b[32m0.0\u001b[39m\n", " - - \u001b[32m1.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " - -\u001b[32m0.0\u001b[39m\n", " digits: \u001b[32m3\u001b[39m\n", "constraints:\n", " omega:\n", " label: omega\n", " low_limit: -\u001b[32m180.0\u001b[39m\n", " high_limit: \u001b[32m180.0\u001b[39m\n", " \u001b[38;5;28;01mclass\u001b[39;00m: LimitsConstraint\n", " chi:\n", " label: chi\n", " low_limit: -\u001b[32m180.0\u001b[39m\n", " high_limit: \u001b[32m180.0\u001b[39m\n", " \u001b[38;5;28;01mclass\u001b[39;00m: LimitsConstraint\n", " phi:\n", " label: phi\n", " low_limit: -\u001b[32m180.0\u001b[39m\n", " high_limit: \u001b[32m180.0\u001b[39m\n", " \u001b[38;5;28;01mclass\u001b[39;00m: LimitsConstraint\n", " tth:\n", " label: tth\n", " low_limit: -\u001b[32m180.0\u001b[39m\n", " high_limit: \u001b[32m180.0\u001b[39m\n", " \u001b[38;5;28;01mclass\u001b[39;00m: LimitsConstraint\n", "solver:\n", " name: hkl_soleil\n", " description: HklSolver(name=\u001b[33m'hkl_soleil'\u001b[39m, version=\u001b[33m'5.1.2'\u001b[39m, geometry=\u001b[33m'E4CV'\u001b[39m, engine_name=\u001b[33m'hkl'\u001b[39m,\n", " mode=\u001b[33m'bissector'\u001b[39m)\n", " geometry: E4CV\n", " real_axes:\n", " - omega\n", " - chi\n", " - phi\n", " - tth\n", " version: \u001b[32m5.1\u001b[39m\u001b[32m.2\u001b[39m\n", " engine: hkl\n" ] } ], "source": [ "%pycat dev_e4cv-vibranium.yml" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Restore (load) Configuration\n", "\n", "To demonstrate restore, let's start again with an unconfigured diffractometer.\n", "We'll just recreate the `sim4c` object. There will only be the default `sample`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sample': Sample(name='sample', lattice=Lattice(a=1, system='cubic'))}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c = hklpy2.creator(name=\"sim4c\")\n", "sim4c.samples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Restore the configuration from the `dev_e4cv-vibranium.yml` file." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "sim4c.restore(\"dev_e4cv-vibranium.yml\", clear=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show the samples again:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sample': Sample(name='sample', lattice=Lattice(a=1, system='cubic')),\n", " 'vibranium': Sample(name='vibranium', lattice=Lattice(a=6.283, system='cubic'))}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c.samples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show the full configuration report again:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'_header': {'datetime': '2025-03-26 12:38:34.229223',\n", " 'hklpy2_version': '0.0.28.dev92+g12cedce.d20250326',\n", " 'python_class': 'Hklpy2Diffractometer',\n", " 'source_type': 'X-ray',\n", " 'energy_units': 'keV',\n", " 'energy': 12.398419843856837,\n", " 'wavelength_units': 'angstrom',\n", " 'wavelength': 1.0},\n", " 'name': 'sim4c',\n", " 'axes': {'pseudo_axes': ['h', 'k', 'l'],\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'axes_xref': {'h': 'h',\n", " 'k': 'k',\n", " 'l': 'l',\n", " 'omega': 'omega',\n", " 'chi': 'chi',\n", " 'phi': 'phi',\n", " 'tth': 'tth'},\n", " 'extra_axes': {}},\n", " 'sample_name': 'vibranium',\n", " 'samples': {'sample': {'name': 'sample',\n", " 'lattice': {'a': 1,\n", " 'b': 1,\n", " 'c': 1,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {},\n", " 'reflections_order': [],\n", " 'U': [[1, 0, 0], [0, 1, 0], [0, 0, 1]],\n", " 'UB': [[6.283185307179586, 0.0, 0.0],\n", " [0.0, 6.283185307179586, 0.0],\n", " [0.0, 0.0, 6.283185307179586]],\n", " 'digits': 4},\n", " 'vibranium': {'name': 'vibranium',\n", " 'lattice': {'a': 6.283185307179586,\n", " 'b': 6.283185307179586,\n", " 'c': 6.283185307179586,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {'r1': {'name': 'r1',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 1, 'k': 0, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': 0, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4},\n", " 'r2': {'name': 'r2',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 0, 'k': 1, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': -90, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4}},\n", " 'reflections_order': ['r1', 'r2'],\n", " 'U': [[-0.0, -0.0, 1.0], [0.0, -1.0, -0.0], [1.0, -0.0, 0.0]],\n", " 'UB': [[-0.0, -0.0, 1.0], [0.0, -1.0, 0.0], [1.0, -0.0, -0.0]],\n", " 'digits': 3}},\n", " 'constraints': {'omega': {'label': 'omega',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'chi': {'label': 'chi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'phi': {'label': 'phi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'tth': {'label': 'tth',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'}},\n", " 'solver': {'name': 'hkl_soleil',\n", " 'description': \"HklSolver(name='hkl_soleil', version='5.1.2', geometry='E4CV', engine_name='hkl', mode='bissector')\",\n", " 'geometry': 'E4CV',\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'version': '5.1.2',\n", " 'engine': 'hkl'}}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c.configuration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The configuration of one or more diffractometers can be saved to the metadata of\n", "each run. To save the configuration(s), an instance of the\n", "[ConfigurationRunWrapper](https://prjemian.github.io/hklpy2/api/z_misc.html)\n", "[preprocessor](https://blueskyproject.io/bluesky/main/plans.html#supplemental-data)\n", "is added to the `RE`.\n", "\n", "This example uses one diffractometer, an Eulerian 4-circle named `sim4c`.\n", "\n", "First, create a simulated 4-circle diffractometer. We'll load the orientation\n", "from the `dev_e4cv-vibranium.yml` file we created above." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import hklpy2\n", "\n", "sim4c = hklpy2.creator(name=\"sim4c\")\n", "sim4c.restore(\"dev_e4cv-vibranium.yml\", clear=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Setup bluesky to run standard plans with the `RunEngine`. Also get `noisy_det`\n", "from the ophyd simulated detectors. To restore a diffractometer configuration\n", "from a previous run, we'll need a catalog (`cat`) of runs." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from bluesky import RunEngine, plans as bp\n", "from ophyd.sim import noisy_det\n", "import databroker\n", "\n", "RE = RunEngine()\n", "cat = databroker.temp().v2\n", "RE.subscribe(cat.v1.insert)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Save configuration with every run\n", "\n", "Create an instance of the `ConfigurationRunWrapper`, adding the `sim4c` diffractometer." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "from hklpy2 import ConfigurationRunWrapper\n", "\n", "crw = ConfigurationRunWrapper(sim4c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add the `crw` instance to the list of preprocessors that are run by the `RE`.\n", "Each one examines the sequence of `Msg` objects internal to the RunEngine. The\n", "`crw.wrapper` method will add the `sim4c` diffractometer's configuration details\n", "to every run's metadata. (Later, we'll show how to read and restore from that\n", "metadata.)\n", "\n", "This configures `RE` to save `sim4c` configuration with every run." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "RE.preprocessors.append(crw.wrapper)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's run a `count` plan using the `noisy_det` detector. Keep track of the\n", "run's `uid`, we'll use that later." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "uids = RE(bp.count([noisy_det]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `sim4c` configuration is saved as a dictionary with the other metadata under\n", "the `\"diffractometers\"` key. This is a dictionary, with a key for each\n", "diffractometer name to be reported. Let's view the `\"diffractometers\"`\n", "dictionary. (Compare with similar views shown above.)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sim4c': {'_header': {'datetime': '2025-03-26 12:38:35.208902',\n", " 'hklpy2_version': '0.0.28.dev92+g12cedce.d20250326',\n", " 'python_class': 'Hklpy2Diffractometer',\n", " 'source_type': 'X-ray',\n", " 'energy_units': 'keV',\n", " 'energy': 12.398419843856837,\n", " 'wavelength_units': 'angstrom',\n", " 'wavelength': 1.0},\n", " 'name': 'sim4c',\n", " 'axes': {'pseudo_axes': ['h', 'k', 'l'],\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'axes_xref': {'h': 'h',\n", " 'k': 'k',\n", " 'l': 'l',\n", " 'omega': 'omega',\n", " 'chi': 'chi',\n", " 'phi': 'phi',\n", " 'tth': 'tth'},\n", " 'extra_axes': {}},\n", " 'sample_name': 'vibranium',\n", " 'samples': {'sample': {'name': 'sample',\n", " 'lattice': {'a': 1,\n", " 'b': 1,\n", " 'c': 1,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {},\n", " 'reflections_order': [],\n", " 'U': [[1, 0, 0], [0, 1, 0], [0, 0, 1]],\n", " 'UB': [[6.283185307179586, 0.0, 0.0],\n", " [0.0, 6.283185307179586, 0.0],\n", " [0.0, 0.0, 6.283185307179586]],\n", " 'digits': 4},\n", " 'vibranium': {'name': 'vibranium',\n", " 'lattice': {'a': 6.283185307179586,\n", " 'b': 6.283185307179586,\n", " 'c': 6.283185307179586,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {'r1': {'name': 'r1',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 1, 'k': 0, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': 0, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4},\n", " 'r2': {'name': 'r2',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 0, 'k': 1, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': -90, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4}},\n", " 'reflections_order': ['r1', 'r2'],\n", " 'U': [[-0.0, -0.0, 1.0], [0.0, -1.0, -0.0], [1.0, -0.0, 0.0]],\n", " 'UB': [[-0.0, -0.0, 1.0], [0.0, -1.0, 0.0], [1.0, -0.0, -0.0]],\n", " 'digits': 3}},\n", " 'constraints': {'omega': {'label': 'omega',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'chi': {'label': 'chi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'phi': {'label': 'phi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'tth': {'label': 'tth',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'}},\n", " 'solver': {'name': 'hkl_soleil',\n", " 'description': \"HklSolver(name='hkl_soleil', version='5.1.2', geometry='E4CV', engine_name='hkl', mode='bissector')\",\n", " 'geometry': 'E4CV',\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'version': '5.1.2',\n", " 'engine': 'hkl'}}}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run = cat.v2[uids[0]]\n", "run.metadata[\"start\"][\"diffractometers\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Restore from previous run\n", "\n", "To restore from a previous run, we must have a reference to the run (with a\n", "`uid`, `scan_id`, run object, ...). In the steps below, we'll use the `run`\n", "object from the previous steps." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BlueskyRun\n", " uid='3a88e279-fb84-43f5-b8fb-df6a3fbfe1d1'\n", " exit_status='success'\n", " 2025-03-26 12:38:35.213 -- 2025-03-26 12:38:35.226\n", " Streams:\n", " * primary\n" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the configuration of the `\"sim4c\"` diffractometer using\n", "`hklpy2.misc.get_run_orientation()`." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "from hklpy2.misc import get_run_orientation\n", "\n", "e4cv_configuration = get_run_orientation(run, name=\"sim4c\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's recreate `sim4c` to prove when we have recovered the configuration.\n", "\n", "Note: This example uses the same name as before but that is not necessary. The\n", "configuration can be restored as long as the solver and geometry match." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sample': Sample(name='sample', lattice=Lattice(a=1, system='cubic'))}" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c = hklpy2.creator(name=\"sim4c\")\n", "sim4c.samples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Restore the configuration (from a previous run) to the `sim4c` diffractometer.\n", "Confirm by examining the sample dictionary." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'_header': {'datetime': '2025-03-26 12:38:35.208902',\n", " 'hklpy2_version': '0.0.28.dev92+g12cedce.d20250326',\n", " 'python_class': 'Hklpy2Diffractometer',\n", " 'source_type': 'X-ray',\n", " 'energy_units': 'keV',\n", " 'energy': 12.398419843856837,\n", " 'wavelength_units': 'angstrom',\n", " 'wavelength': 1.0},\n", " 'name': 'sim4c',\n", " 'axes': {'pseudo_axes': ['h', 'k', 'l'],\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'axes_xref': {'h': 'h',\n", " 'k': 'k',\n", " 'l': 'l',\n", " 'omega': 'omega',\n", " 'chi': 'chi',\n", " 'phi': 'phi',\n", " 'tth': 'tth'},\n", " 'extra_axes': {}},\n", " 'sample_name': 'vibranium',\n", " 'samples': {'sample': {'name': 'sample',\n", " 'lattice': {'a': 1,\n", " 'b': 1,\n", " 'c': 1,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {},\n", " 'reflections_order': [],\n", " 'U': [[1, 0, 0], [0, 1, 0], [0, 0, 1]],\n", " 'UB': [[6.283185307179586, 0.0, 0.0],\n", " [0.0, 6.283185307179586, 0.0],\n", " [0.0, 0.0, 6.283185307179586]],\n", " 'digits': 4},\n", " 'vibranium': {'name': 'vibranium',\n", " 'lattice': {'a': 6.283185307179586,\n", " 'b': 6.283185307179586,\n", " 'c': 6.283185307179586,\n", " 'alpha': 90.0,\n", " 'beta': 90.0,\n", " 'gamma': 90.0},\n", " 'reflections': {'r1': {'name': 'r1',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 1, 'k': 0, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': 0, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4},\n", " 'r2': {'name': 'r2',\n", " 'geometry': 'E4CV',\n", " 'pseudos': {'h': 0, 'k': 1, 'l': 0},\n", " 'reals': {'omega': 10, 'chi': -90, 'phi': 0, 'tth': 20},\n", " 'wavelength': 1.0,\n", " 'digits': 4}},\n", " 'reflections_order': ['r1', 'r2'],\n", " 'U': [[-0.0, -0.0, 1.0], [0.0, -1.0, -0.0], [1.0, -0.0, 0.0]],\n", " 'UB': [[-0.0, -0.0, 1.0], [0.0, -1.0, 0.0], [1.0, -0.0, -0.0]],\n", " 'digits': 3}},\n", " 'constraints': {'omega': {'label': 'omega',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'chi': {'label': 'chi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'phi': {'label': 'phi',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'},\n", " 'tth': {'label': 'tth',\n", " 'low_limit': -180.0,\n", " 'high_limit': 180.0,\n", " 'class': 'LimitsConstraint'}},\n", " 'solver': {'name': 'hkl_soleil',\n", " 'description': \"HklSolver(name='hkl_soleil', version='5.1.2', geometry='E4CV', engine_name='hkl', mode='bissector')\",\n", " 'geometry': 'E4CV',\n", " 'real_axes': ['omega', 'chi', 'phi', 'tth'],\n", " 'version': '5.1.2',\n", " 'engine': 'hkl'}}" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "e4cv_configuration" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sample': Sample(name='sample', lattice=Lattice(a=1, system='cubic')),\n", " 'vibranium': Sample(name='vibranium', lattice=Lattice(a=6.283, system='cubic'))}" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sim4c.configuration = e4cv_configuration\n", "sim4c.samples" ] } ], "metadata": { "kernelspec": { "display_name": "base", "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.13.2" } }, "nbformat": 4, "nbformat_minor": 2 }