Sample orientation: export & restore diffractometer configuration#

A common user request is to preserve the orientation (UB) matrix and related terms used to compute it. Terms such as the list of orientation reflections, samples, and diffractometer geometry from their current session. The configuration should be saved somewhere so it is available, even after bluesky stops. Multiple sessions could (optionally) access the same configuration or use a different one.

It is a local choice how and where to save this configuration. The first step is to define a common structure to be exported and restored by hklpy. The structure would be stored in any of a variety of possibilities (some of these are provided by hklpy, the others are suggestions).

  • text file: stored in:

    • the local file directory

    • some other directory

    • network storage

  • NeXus HDF5 file: stored in the pwd or elsewhere

  • EPICS Channel Access string waveform record

  • EPICS pvAccess structure

  • in-memory cache, such as:

  • database, such as:

  • Python object: (such as used in this documentation)

    • dictionary

    • JSON string

    • YAML string

A session could restore the configuration automatically from the chosen storage. Later, the session would export the configuration both automatically, and to a different location at the choice of the user.

Objective

Show how to export diffractometer configuration to a file and later restore it. Demonstrate with a 4-circle diffractometer (E4CV geometry).

Setup a (simulated) 4-circle diffractometer#

Load the support for a 4-circle diffractometer using the E4CV geometry. Since this is a simulation, we do not need an EPICS system with motors. The SimulatedE4CV structure (a Python class) provides all that is needed.

[1]:
from hkl import SimulatedE4CV

sim4c = SimulatedE4CV("", name="sim4c")

Print all the details about this sim4c diffractometer we just created. Since this is a default configuration, no orientation reflections have been reported. The UB matrix is the default \((2\pi/1.54)\)U where U is the identity matrix and 1.54 is the unit cell length. The geometry defines the names of the rotational axes omega, chi, phi, and tth. This is the canonical order. The constraints are applied when computing values for the rotational axes from reciprocal space coordinates.

[2]:
sim4c.pa()
===================== ====================================================================
term                  value
===================== ====================================================================
diffractometer        sim4c
geometry              E4CV
class                 SimulatedE4CV
energy (keV)          8.05092
wavelength (angstrom) 1.54000
calc engine           hkl
mode                  bissector
positions             ===== =======
                      name  value
                      ===== =======
                      omega 0.00000
                      chi   0.00000
                      phi   0.00000
                      tth   0.00000
                      ===== =======
constraints           ===== ========= ========== ===== ====
                      axis  low_limit high_limit value fit
                      ===== ========= ========== ===== ====
                      omega -180.0    180.0      0.0   True
                      chi   -180.0    180.0      0.0   True
                      phi   -180.0    180.0      0.0   True
                      tth   -180.0    180.0      0.0   True
                      ===== ========= ========== ===== ====
sample: main          ================ ===================================================
                      term             value
                      ================ ===================================================
                      unit cell edges  a=1.54, b=1.54, c=1.54
                      unit cell angles alpha=90.0, beta=90.0, gamma=90.0
                      [U]              [[1. 0. 0.]
                                        [0. 1. 0.]
                                        [0. 0. 1.]]
                      [UB]             [[ 4.07999046e+00 -2.49827363e-16 -2.49827363e-16]
                                        [ 0.00000000e+00  4.07999046e+00 -2.49827363e-16]
                                        [ 0.00000000e+00  0.00000000e+00  4.07999046e+00]]
                      ================ ===================================================
===================== ====================================================================

[2]:
<pyRestTable.rest_table.Table at 0x7f3b75440750>

What is described in a diffractometer configuration?#

The hkl.DiffractometerConfiguration structure is used for export and restore. To show what an export contains (for this default diffractometer), we make a Python object specifically for the sim4c diffractometer. In this example, the object is called agent (you could pick some other name, such as config).

Create agent specifically for the sim4c diffractometer to provide the methods in the next table.

Python

description

agent.export()

describe a diffractometer’s configuration

agent.preview()

preview a saved configuration

agent.restore()

set a diffractometer’s configuration

[3]:
from hkl import DiffractometerConfiguration

agent = DiffractometerConfiguration(sim4c)

Export#

export() returns the current configuration of the diffractometer in any of several formats:

  • JSON string (default)

  • YAML string

  • Python dictionary

  • file (as defined by a Python pathlib object)

Note: Internally, the code uses the Python dictionary for the actual export and restore operations. The other formats derive from the Python dictionary. All information in the Python dictionary is first validated before it is restored to the diffractometer.

Export: JSON string (default) format#

Describe sim4c using agent.export(). The information content is similar to sim4c.pa(), but in a format convenient for both saving (to a file or other structure) and for restoring.

The default format is a JSON string, formatted with line endings and indentation. (Alternatives include Python dictionary, YAML, and file.)

[4]:
print(agent.export())
{
  "geometry": "E4CV",
  "engine": "hkl",
  "library": "gi.repository.Hkl",
  "mode": "bissector",
  "canonical_axes": [
    "omega",
    "chi",
    "phi",
    "tth"
  ],
  "real_axes": [
    "omega",
    "chi",
    "phi",
    "tth"
  ],
  "reciprocal_axes": [
    "h",
    "k",
    "l"
  ],
  "constraints": {
    "omega": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "chi": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "phi": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "tth": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    }
  },
  "samples": {
    "main": {
      "name": "main",
      "lattice": {
        "a": 1.54,
        "b": 1.54,
        "c": 1.54,
        "alpha": 90.0,
        "beta": 90.0,
        "gamma": 90.0
      },
      "reflections": [],
      "UB": [
        [
          4.079990459207523,
          -2.4982736282101165e-16,
          -2.4982736282101165e-16
        ],
        [
          0.0,
          4.079990459207523,
          -2.4982736282101165e-16
        ],
        [
          0.0,
          0.0,
          4.079990459207523
        ]
      ],
      "U": [
        [
          1.0,
          0.0,
          0.0
        ],
        [
          0.0,
          1.0,
          0.0
        ],
        [
          0.0,
          0.0,
          1.0
        ]
      ]
    }
  },
  "name": "sim4c",
  "datetime": "2023-11-16 12:48:44.500249",
  "wavelength_angstrom": 1.54,
  "energy_keV": 8.050921974025975,
  "hklpy_version": "1.0.5.dev207+g955ab4d",
  "library_version": "v5.0.0.3001",
  "python_class": "SimulatedE4CV",
  "other": {}
}

Export: YAML string format#

View the same content in YAML format:

[5]:
print(agent.export("yaml"))
geometry: E4CV
engine: hkl
library: gi.repository.Hkl
mode: bissector
canonical_axes:
- omega
- chi
- phi
- tth
real_axes:
- omega
- chi
- phi
- tth
reciprocal_axes:
- h
- k
- l
constraints:
  omega:
    low_limit: -180.0
    high_limit: 180.0
    value: 0.0
    fit: true
  chi:
    low_limit: -180.0
    high_limit: 180.0
    value: 0.0
    fit: true
  phi:
    low_limit: -180.0
    high_limit: 180.0
    value: 0.0
    fit: true
  tth:
    low_limit: -180.0
    high_limit: 180.0
    value: 0.0
    fit: true
samples:
  main:
    name: main
    lattice:
      a: 1.54
      b: 1.54
      c: 1.54
      alpha: 90.0
      beta: 90.0
      gamma: 90.0
    reflections: []
    UB:
    - - 4.079990459207523
      - -2.4982736282101165e-16
      - -2.4982736282101165e-16
    - - 0.0
      - 4.079990459207523
      - -2.4982736282101165e-16
    - - 0.0
      - 0.0
      - 4.079990459207523
    U:
    - - 1.0
      - 0.0
      - 0.0
    - - 0.0
      - 1.0
      - 0.0
    - - 0.0
      - 0.0
      - 1.0
name: sim4c
datetime: '2023-11-16 12:48:44.571162'
wavelength_angstrom: 1.54
energy_keV: 8.050921974025975
hklpy_version: 1.0.5.dev207+g955ab4d
library_version: v5.0.0.3001
python_class: SimulatedE4CV
other: {}

Export: Python dictionary format#

Or as Python dictionary:

[6]:
agent.export("dict")
[6]:
{'geometry': 'E4CV',
 'engine': 'hkl',
 'library': 'gi.repository.Hkl',
 'mode': 'bissector',
 'canonical_axes': ['omega', 'chi', 'phi', 'tth'],
 'real_axes': ['omega', 'chi', 'phi', 'tth'],
 'reciprocal_axes': ['h', 'k', 'l'],
 'constraints': {'omega': {'low_limit': -180.0,
   'high_limit': 180.0,
   'value': 0.0,
   'fit': True},
  'chi': {'low_limit': -180.0, 'high_limit': 180.0, 'value': 0.0, 'fit': True},
  'phi': {'low_limit': -180.0, 'high_limit': 180.0, 'value': 0.0, 'fit': True},
  'tth': {'low_limit': -180.0,
   'high_limit': 180.0,
   'value': 0.0,
   'fit': True}},
 'samples': {'main': {'name': 'main',
   'lattice': {'a': 1.54,
    'b': 1.54,
    'c': 1.54,
    'alpha': 90.0,
    'beta': 90.0,
    'gamma': 90.0},
   'reflections': [],
   'UB': [[4.079990459207523,
     -2.4982736282101165e-16,
     -2.4982736282101165e-16],
    [0.0, 4.079990459207523, -2.4982736282101165e-16],
    [0.0, 0.0, 4.079990459207523]],
   'U': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]}},
 'name': 'sim4c',
 'datetime': '2023-11-16 12:48:44.578586',
 'wavelength_angstrom': 1.54,
 'energy_keV': 8.050921974025975,
 'hklpy_version': '1.0.5.dev207+g955ab4d',
 'library_version': 'v5.0.0.3001',
 'python_class': 'SimulatedE4CV',
 'other': {}}

Export: Data file (text)#

Or as a data file. To save as a data file, we need the name (and directory path) of that file. Could be a local file such as sim4c-config.json or a file in some other directory such as ~/.config/sim4c/autosave.json. These are just ideas.

In any case, we describe the file name and path using Python’s pathlib support package.

For this example, we’ll use files created just for this notebook in a temporary directory using Python’s tempfile package. The entire directory will be deleted when the notebook exits. (The iterdir() method prints the directory’s contents. It’s empty at the start.)

[7]:
import pathlib
import tempfile

temp_dir = tempfile.TemporaryDirectory()
config_path = pathlib.Path(temp_dir.name)
print(f"{config_path=}")
print(f"{list(config_path.iterdir())=}")
config_path=PosixPath('/tmp/tmpvrwz9f7z')
list(config_path.iterdir())=[]

Export the configuration to file sim4c.json in the temporary directory. Show the file exists.

[8]:
config_file = config_path / "sim4c.json"
agent.export(config_file)
print(f"{list(config_path.iterdir())=}")
list(config_path.iterdir())=[PosixPath('/tmp/tmpvrwz9f7z/sim4c.json')]

Show the contents of the new configuration file.

[9]:
with open(config_file) as f:
    print(f.read())
{
  "geometry": "E4CV",
  "engine": "hkl",
  "library": "gi.repository.Hkl",
  "mode": "bissector",
  "canonical_axes": [
    "omega",
    "chi",
    "phi",
    "tth"
  ],
  "real_axes": [
    "omega",
    "chi",
    "phi",
    "tth"
  ],
  "reciprocal_axes": [
    "h",
    "k",
    "l"
  ],
  "constraints": {
    "omega": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "chi": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "phi": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    },
    "tth": {
      "low_limit": -180.0,
      "high_limit": 180.0,
      "value": 0.0,
      "fit": true
    }
  },
  "samples": {
    "main": {
      "name": "main",
      "lattice": {
        "a": 1.54,
        "b": 1.54,
        "c": 1.54,
        "alpha": 90.0,
        "beta": 90.0,
        "gamma": 90.0
      },
      "reflections": [],
      "UB": [
        [
          4.079990459207523,
          -2.4982736282101165e-16,
          -2.4982736282101165e-16
        ],
        [
          0.0,
          4.079990459207523,
          -2.4982736282101165e-16
        ],
        [
          0.0,
          0.0,
          4.079990459207523
        ]
      ],
      "U": [
        [
          1.0,
          0.0,
          0.0
        ],
        [
          0.0,
          1.0,
          0.0
        ],
        [
          0.0,
          0.0,
          1.0
        ]
      ]
    }
  },
  "name": "sim4c",
  "datetime": "2023-11-16 12:48:44.591289",
  "wavelength_angstrom": 1.54,
  "energy_keV": 8.050921974025975,
  "hklpy_version": "1.0.5.dev207+g955ab4d",
  "library_version": "v5.0.0.3001",
  "python_class": "SimulatedE4CV",
  "other": {}
}

Preview & Restore#

To demonstrate agent.preview() and agent.restore(), let’s compare the file we just wrote with a file found on the internet. The hklpy repository on GitHub has a compatible (same geometry, canonical motor names, and back-end computation library) file used for testing the hklpy source code.

We’ll use the requests package for the download. With requests, we can keep the structure in memory. (There is no need to save it to a local file.)

[10]:
import requests

r = requests.get(
    "https://raw.githubusercontent.com/bluesky/hklpy/main/hkl/tests/data/e4c-config.json"
)
test_e4c_config = r.text
print(f"{test_e4c_config=}")
test_e4c_config='{\n    "geometry": "E4CV",\n    "engine": "hkl",\n    "library": "gi.repository.Hkl",\n    "mode": "bissector",\n    "canonical_axes": [\n        "omega",\n        "chi",\n        "phi",\n        "tth"\n    ],\n    "real_axes": [\n        "omega",\n        "chi",\n        "phi",\n        "tth"\n    ],\n    "reciprocal_axes": [\n        "h",\n        "k",\n        "l"\n    ],\n    "constraints": {\n        "omega": {\n            "low_limit": -100.0,\n            "high_limit": 100.0,\n            "value": 0.0,\n            "fit": true\n        },\n        "chi": {\n            "low_limit": -100.0,\n            "high_limit": 100.0,\n            "value": 0.0,\n            "fit": true\n        },\n        "phi": {\n            "low_limit": -100.0,\n            "high_limit": 100.0,\n            "value": 0.0,\n            "fit": true\n        },\n        "tth": {\n            "low_limit": -100.0,\n            "high_limit": 100.0,\n            "value": 0.0,\n            "fit": true\n        }\n    },\n    "samples": {\n        "main": {\n            "name": "main",\n            "lattice": {\n                "a": 1.54,\n                "b": 1.54,\n                "c": 1.54,\n                "alpha": 90.0,\n                "beta": 90.0,\n                "gamma": 90.0\n            },\n            "reflections": [],\n            "UB": [\n                [\n                    4.079990459207523,\n                    -2.4982736282101165e-16,\n                    -2.4982736282101165e-16\n                ],\n                [\n                    0.0,\n                    4.079990459207523,\n                    -2.4982736282101165e-16\n                ],\n                [\n                    0.0,\n                    0.0,\n                    4.079990459207523\n                ]\n            ],\n            "U": [\n                [\n                    1.0,\n                    0.0,\n                    0.0\n                ],\n                [\n                    0.0,\n                    1.0,\n                    0.0\n                ],\n                [\n                    0.0,\n                    0.0,\n                    1.0\n                ]\n            ]\n        },\n        "vibranium": {\n            "name": "vibranium",\n            "lattice": {\n                "a": 6.283185307179586,\n                "b": 6.283185307179586,\n                "c": 6.283185307179586,\n                "alpha": 90.0,\n                "beta": 90.0,\n                "gamma": 90.0\n            },\n            "reflections": [\n                {\n                    "reflection": {\n                        "h": 4.0,\n                        "k": 0.0,\n                        "l": 0.0\n                    },\n                    "position": {\n                        "omega": -145.451,\n                        "chi": 0.0,\n                        "phi": 0.0,\n                        "tth": 69.0966\n                    },\n                    "wavelength": 1.54,\n                    "orientation_reflection": false,\n                    "flag": 1\n                },\n                {\n                    "reflection": {\n                        "h": 0.0,\n                        "k": 4.0,\n                        "l": 0.0\n                    },\n                    "position": {\n                        "omega": -145.451,\n                        "chi": 0.0,\n                        "phi": 90.0,\n                        "tth": 69.0966\n                    },\n                    "wavelength": 1.54,\n                    "orientation_reflection": true,\n                    "flag": 1\n                },\n                {\n                    "reflection": {\n                        "h": 0.0,\n                        "k": 0.0,\n                        "l": 4.0\n                    },\n                    "position": {\n                        "omega": -145.451,\n                        "chi": 90.0,\n                        "phi": 0.0,\n                        "tth": 69.0966\n                    },\n                    "wavelength": 1.54,\n                    "orientation_reflection": true,\n                    "flag": 1\n                }\n            ],\n            "UB": [\n                [\n                    1.2217304763701863e-05,\n                    -0.9999999999253688,\n                    -1.7623547209572502e-15\n                ],\n                [\n                    -1.4926257043558267e-10,\n                    -1.4349296274686127e-42,\n                    -1.0000000000000002\n                ],\n                [\n                    0.9999999999253688,\n                    1.221730476364063e-05,\n                    -1.492626316575311e-10\n                ]\n            ],\n            "U": [\n                [\n                    1.2217304763701863e-05,\n                    -0.9999999999253688,\n                    -1.8235863128158895e-15\n                ],\n                [\n                    -1.4926257043558267e-10,\n                    -9.139696455822134e-27,\n                    -1.0000000000000002\n                ],\n                [\n                    0.9999999999253688,\n                    1.2217304763701863e-05,\n                    -1.4926257042444305e-10\n                ]\n            ]\n        }\n    },\n    "name": "e4c",\n    "datetime": "2023-11-01 16:40",\n    "wavelength_angstrom": 1.54,\n    "energy_keV": 8.050921974025975,\n    "hklpy_version": "1.0.5.dev122+g473f61f",\n    "library_version": "v5.0.0.3001",\n    "python_class": "SimulatedE4CV",\n    "other": {}\n}\n'

Preview: JSON string#

The agent.preview(structure) method shows the sample information (name, crystal lattice parameters, and number of orientation reflections) from the configuration structure object, without loading it into the diffractometer.

agent.preview() works with these types of structure:

  • JSON string

  • YAML string

  • Python dictionary

  • file (pathlib object)

Here, test_e4c_config is recognized as a JSON string.

[11]:
print(type(test_e4c_config))
print(agent.preview(test_e4c_config))
<class 'str'>
name: e4c
date: 2023-11-01 16:40
geometry: E4CV

Table of Samples
= ========= ========= ========= ========= ===== ==== ===== =====
# sample    a         b         c         alpha beta gamma #refl
= ========= ========= ========= ========= ===== ==== ===== =====
1 main      1.54      1.54      1.54      90.0  90.0 90.0  0
2 vibranium 6.2831853 6.2831853 6.2831853 90.0  90.0 90.0  3
= ========= ========= ========= ========= ===== ==== ===== =====

See that test_e4c_config has an additional sample: vibranium (looks cubic with a lattice constant \(a_o=2\pi\) which is right since vibranium is fictional). Three orientation reflections are provided. Next, show the additional details.

[12]:
# options to show constraints and list of reflections
print(agent.preview(test_e4c_config, show_constraints=True, show_reflections=True))
name: e4c
date: 2023-11-01 16:40
geometry: E4CV

Table of Samples
= ========= ========= ========= ========= ===== ==== ===== =====
# sample    a         b         c         alpha beta gamma #refl
= ========= ========= ========= ========= ===== ==== ===== =====
1 main      1.54      1.54      1.54      90.0  90.0 90.0  0
2 vibranium 6.2831853 6.2831853 6.2831853 90.0  90.0 90.0  3
= ========= ========= ========= ========= ===== ==== ===== =====


Table of Reflections for Sample: vibranium
= === === === ======== ==== ==== ======= ========== =======
# h   k   l   omega    chi  phi  tth     wavelength orient?
= === === === ======== ==== ==== ======= ========== =======
1 4.0 0.0 0.0 -145.451 0.0  0.0  69.0966 1.54       False
2 0.0 4.0 0.0 -145.451 0.0  90.0 69.0966 1.54       True
3 0.0 0.0 4.0 -145.451 90.0 0.0  69.0966 1.54       True
= === === === ======== ==== ==== ======= ========== =======


Table of Axis Constraints
===== ========= ========== ===== ====
axis  low_limit high_limit value fit?
===== ========= ========== ===== ====
omega -100.0    100.0      0.0   True
chi   -100.0    100.0      0.0   True
phi   -100.0    100.0      0.0   True
tth   -100.0    100.0      0.0   True
===== ========= ========== ===== ====

Note that the high and low limits in the constraints are now \(\pm100\). In the default, they were \(\pm180\).

Restore: JSON string#

Let’s restore the test_e4c_config configuration to our sim4c diffractometer. This is possible because we have identical matches of the diffractometer and the configuration:

  • name of geometry

  • name of computation engine

  • name of back-end support library

  • names and exact order of reciprocal-space axes

  • names and exact order of canonical real-space axes

(Other validation steps are applied to make sure that the data in the configuration is specified correctly.)

Once restore is complete, print all the diffractometer settings, as before using sim4c.pa().

Note: The agent.restore() method does not move any axes of the diffractometer. It only changes configuration settings in Python memory.

[13]:
agent.restore(test_e4c_config)
sim4c.pa()
===================== ===============================================================================
term                  value
===================== ===============================================================================
diffractometer        sim4c
geometry              E4CV
class                 SimulatedE4CV
energy (keV)          8.05092
wavelength (angstrom) 1.54000
calc engine           hkl
mode                  bissector
positions             ===== =======
                      name  value
                      ===== =======
                      omega 0.00000
                      chi   0.00000
                      phi   0.00000
                      tth   0.00000
                      ===== =======
constraints           ===== ========= ========== ===== ====
                      axis  low_limit high_limit value fit
                      ===== ========= ========== ===== ====
                      omega -100.0    100.0      0.0   True
                      chi   -100.0    100.0      0.0   True
                      phi   -100.0    100.0      0.0   True
                      tth   -100.0    100.0      0.0   True
                      ===== ========= ========== ===== ====
sample: vibranium     ================= =============================================================
                      term              value
                      ================= =============================================================
                      unit cell edges   a=6.283185307179586, b=6.283185307179586, c=6.283185307179586
                      unit cell angles  alpha=90.0, beta=90.0, gamma=90.0
                      ref 1 (hkl)       h=4.0, k=0.0, l=0.0
                      ref 1 positioners omega=-145.45100, chi=0.00000, phi=0.00000, tth=69.09660
                      ref 2 (hkl)       h=0.0, k=4.0, l=0.0
                      ref 2 positioners omega=-145.45100, chi=0.00000, phi=90.00000, tth=69.09660
                      ref 3 (hkl)       h=0.0, k=0.0, l=4.0
                      ref 3 positioners omega=-145.45100, chi=90.00000, phi=0.00000, tth=69.09660
                      [U]               [[ 1.22173048e-05 -1.00000000e+00 -1.82358631e-15]
                                         [-1.49262570e-10 -9.13969646e-27 -1.00000000e+00]
                                         [ 1.00000000e+00  1.22173048e-05 -1.49262570e-10]]
                      [UB]              [[ 1.22173048e-05 -1.00000000e+00 -1.76235472e-15]
                                         [-1.49262570e-10 -1.43492963e-42 -1.00000000e+00]
                                         [ 1.00000000e+00  1.22173048e-05 -1.49262632e-10]]
                      ================= =============================================================
===================== ===============================================================================

[13]:
<pyRestTable.rest_table.Table at 0x7f3b646bb910>

Observe the list of three vibranium sample reflections. Two of them, as noted, have been used to compute the UB matrix.

Restore: file#

We can swap back to the default settings by restoring from the temporary configuration file we created above. This resets the constraints and removes the vibranium sample.

[14]:
agent.restore(config_file)
sim4c.pa()
===================== ====================================================================
term                  value
===================== ====================================================================
diffractometer        sim4c
geometry              E4CV
class                 SimulatedE4CV
energy (keV)          8.05092
wavelength (angstrom) 1.54000
calc engine           hkl
mode                  bissector
positions             ===== =======
                      name  value
                      ===== =======
                      omega 0.00000
                      chi   0.00000
                      phi   0.00000
                      tth   0.00000
                      ===== =======
constraints           ===== ========= ========== ===== ====
                      axis  low_limit high_limit value fit
                      ===== ========= ========== ===== ====
                      omega -180.0    180.0      0.0   True
                      chi   -180.0    180.0      0.0   True
                      phi   -180.0    180.0      0.0   True
                      tth   -180.0    180.0      0.0   True
                      ===== ========= ========== ===== ====
sample: main          ================ ===================================================
                      term             value
                      ================ ===================================================
                      unit cell edges  a=1.54, b=1.54, c=1.54
                      unit cell angles alpha=90.0, beta=90.0, gamma=90.0
                      [U]              [[1. 0. 0.]
                                        [0. 1. 0.]
                                        [0. 0. 1.]]
                      [UB]             [[ 4.07999046e+00 -2.49827363e-16 -2.49827363e-16]
                                        [ 0.00000000e+00  4.07999046e+00 -2.49827363e-16]
                                        [ 0.00000000e+00  0.00000000e+00  4.07999046e+00]]
                      ================ ===================================================
===================== ====================================================================

[14]:
<pyRestTable.rest_table.Table at 0x7f3b74433390>