From 2bd334d3c97b070b7da2b1ac8ebc20d7c68bc64d Mon Sep 17 00:00:00 2001 From: Pete R Jemian Date: Sat, 23 Dec 2023 14:48:40 -0600 Subject: [PATCH] MNT #318 enable use of databroker v2+ --- RELEASE_NOTES.rst | 4 +- environment.yml | 2 +- hkl/tests/test_save_restore_UB.py | 72 +++++++++++++++++++++++-------- hkl/util.py | 48 +++++++++++++-------- pyproject.toml | 4 +- 5 files changed, 87 insertions(+), 43 deletions(-) diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 91d0379c..9947a126 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -39,8 +39,9 @@ Fixes ----- * ``diffract.forward()`` should pick solution consistent with ``diffract.forward_solution_table()``, if it can. Otherwise, fall back to previous iterative method. +* Make ``util.list_orientation_runs()`` work with databroker v1.2 or v2+. +* Make ``util.run_orientation_info()`` work with databroker v1.2 or v2+. * Resolved under-reported problems in CI unit tests. -* Raise ValueError in ``util.run_orientation_info()`` for databroker v2+. * ``util.restore_reflections()`` use renamed motor axes if so defined. Maintenance @@ -53,7 +54,6 @@ Maintenance * Documentation ZIP file uploaded as artifact with each build. Great for review! * Expand testing to to Py3.8 - Py3.11. * Fix code in ``util.restore_reflections()`` that failed unit tests locally. -* Pin databroker 1.2 (issues #316 & #318). * Make it easier to find the SPEC command cross-reference table. * Update packaging to latest PyPA recommendations. * Validate user input to sample.add_reflection(). diff --git a/environment.yml b/environment.yml index 9b633d7c..093a7779 100644 --- a/environment.yml +++ b/environment.yml @@ -15,7 +15,7 @@ dependencies: - python >=3.8,<3.12 - apischema - bluesky - - databroker =1.2 + - databroker - hkl - numpy - ophyd diff --git a/hkl/tests/test_save_restore_UB.py b/hkl/tests/test_save_restore_UB.py index 9f44e6d0..7ca4fddb 100644 --- a/hkl/tests/test_save_restore_UB.py +++ b/hkl/tests/test_save_restore_UB.py @@ -1,3 +1,5 @@ +import time + import bluesky.plans as bp import databroker import numpy.testing @@ -84,18 +86,16 @@ def test_fourc_orientation_save(cat, RE, fourc): # this run will not save orientation information _uids = RE(bp.count([det])) assert len(_uids) == 1 + time.sleep(1) assert len(cat) == 1 assert "fourc" not in cat[1].primary.config # this run _will_ save orientation information _uids = RE(bp.count([det, fourc])) assert len(_uids) == 1 + time.sleep(1) assert len(cat) == 2 - xarray_data = cat[2].primary.config["fourc"].read() - assert not isinstance(xarray_data, dict) - descriptors = xarray_data.to_dict() - assert isinstance(descriptors, dict) - assert list(descriptors.keys()) == "coords attrs dims data_vars".split() + key_list = """ _pseudos _reals @@ -108,20 +108,54 @@ def test_fourc_orientation_save(cat, RE, fourc): sample_name UB """.split() - for key in key_list: - key_name = f"fourc_{key}" - assert hasattr(xarray_data, key_name) - assert key_name in descriptors["data_vars"] - - assert xarray_data.fourc_class_name == "Fourc" - assert xarray_data.fourc_geometry_name == "E4CV" - assert xarray_data.fourc_diffractometer_name == "fourc" - assert xarray_data.fourc_sample_name == "Si" - - assert len(xarray_data.fourc__pseudos) == 1 - assert xarray_data.fourc__pseudos[0].values.tolist() == "h k l".split() - assert len(xarray_data.fourc__reals) == 1 - assert xarray_data.fourc__reals.values[0].tolist() == "omega chi phi tth".split() + + if databroker.__version__ < "2.0": + conf = cat[_uids[0]].primary.config["fourc"].read() + assert not isinstance(conf, dict) + descriptors = conf.to_dict() + assert isinstance(descriptors, dict) + assert list(descriptors.keys()) == "coords attrs dims data_vars".split() + for key in key_list: + key_name = f"fourc_{key}" + assert hasattr(conf, key_name) + assert key_name in descriptors["data_vars"] + + assert conf.fourc_class_name == "Fourc" + assert conf.fourc_geometry_name == "E4CV" + assert conf.fourc_diffractometer_name == "fourc" + assert conf.fourc_sample_name == "Si" + + assert len(conf.fourc__pseudos) == 1 + assert conf.fourc__pseudos[0].values.tolist() == "h k l".split() + assert len(conf.fourc__reals) == 1 + assert conf.fourc__reals.values[0].tolist() == "omega chi phi tth".split() + + else: + descriptors = cat[_uids[0]].primary.descriptors + assert isinstance(descriptors, list) + assert len(descriptors) > 0 + for descriptor in descriptors: + for device, configuration in descriptor.get("configuration", {}).items(): + assert isinstance(device, str) + assert isinstance(configuration, dict) + conf = configuration.get("data", {}) + assert isinstance(conf, dict) + + if device != "fourc": + continue + for key in key_list: + key_name = f"fourc_{key}" + assert key_name in conf + + assert conf["fourc_class_name"] == "Fourc" + assert conf["fourc_geometry_name"] == "E4CV" + assert conf["fourc_diffractometer_name"] == "fourc" + assert conf["fourc_sample_name"] == "Si" + + assert len(conf["fourc__pseudos"]) == 3 + assert conf["fourc__pseudos"] == "h k l".split() + assert len(conf["fourc__reals"]) == 4 + assert conf["fourc__reals"] == "omega chi phi tth".split() def test_fourc_run_orientation_info(cat, RE, fourc): diff --git a/hkl/util.py b/hkl/util.py index 5825a285..0704980f 100644 --- a/hkl/util.py +++ b/hkl/util.py @@ -32,6 +32,7 @@ from collections import defaultdict from collections import namedtuple +import databroker import gi import numpy as np import pandas as pd @@ -306,7 +307,10 @@ def list_orientation_runs(catalog, *args, limit=20): info = run_orientation_info(run) if len(info): scan_id = run.metadata["start"]["scan_id"] - uid = run.name[:7] + if databroker.__version__ >= "2.0": + uid = run.start["uid"][:7] + else: + uid = run.name[:7] for device in sorted(info.keys()): orientation = info[device] row = dict(scan_id=scan_id) @@ -339,26 +343,32 @@ def run_orientation_info(run): run : from Databroker A Bluesky run, from databroker v2, such as ``cat.v2[-1]``. """ - import databroker - - if databroker.__version__ >= "2.0": - raise ValueError( - f"This function does not work with databroker {databroker.__version__}." - " See https://github.com/bluesky/hklpy/pull/317 for details." - ) - devices = {} + try: - run_conf = run.primary.config - for device in sorted(run_conf): - conf = run_conf[device].read() - if f"{device}_orientation_attrs" in conf: - # fmt:off - devices[device] = { - item[len(device)+1:]: conf[item].to_dict()["data"][0] - for item in conf - } - # fmt:on + if databroker.__version__ >= "2.0": + for descriptor in run.primary.descriptors: + for device, configuration in descriptor.get("configuration", {}).items(): + conf = configuration.get("data", {}) + if f"{device}_orientation_attrs" in conf: + # fmt:off + devices[device] = { + item[len(device) + 1:]: value + for item, value in conf.items() + } + # fmt:on + + else: # older databroker v1.2 + run_conf = run.primary.config + for device in sorted(run_conf): + conf = run_conf[device].read() + if f"{device}_orientation_attrs" in conf: + # fmt:off + devices[device] = { + item[len(device)+1:]: conf[item].to_dict()["data"][0] + for item in conf + } + # fmt:on except Exception as exc: logger.warning("Could not process run %s, due to %s", run, exc) return devices diff --git a/pyproject.toml b/pyproject.toml index e9906d6a..a8197336 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ classifiers = [ # pyqt ==5 dependencies = [ "apischema", - "databroker ==1.2", + "databroker", "numpy", "ophyd", "pint", @@ -65,7 +65,7 @@ docs = [ ] tests = [ "bluesky", - "tiled <=0.1.0a96", + "tiled", "packaging", ] all = ["hklpy[docs,tests]"]