From 0e9b1ed5896fb7423871ee74e8077c46baa86460 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver <thomas.kluyver@xfel.eu> Date: Tue, 26 Mar 2024 14:19:27 +0000 Subject: [PATCH] Backport CalCat CCV metadata API from EXtra --- src/cal_tools/calcat_interface2.py | 36 +++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/cal_tools/calcat_interface2.py b/src/cal_tools/calcat_interface2.py index 20132d45e..0985c8925 100644 --- a/src/cal_tools/calcat_interface2.py +++ b/src/cal_tools/calcat_interface2.py @@ -1,7 +1,7 @@ import json import re from collections.abc import Mapping -from dataclasses import dataclass, replace +from dataclasses import dataclass, field, replace from datetime import date, datetime, time, timezone from functools import lru_cache from pathlib import Path @@ -244,6 +244,8 @@ class SingleConstant: dataset: str ccv_id: Optional[int] pdu_name: Optional[str] + _metadata: dict = field(default_factory=dict) + _have_calcat_metadata: bool = False @classmethod def from_response(cls, ccv: dict) -> "SingleConstant": @@ -252,6 +254,8 @@ class SingleConstant: dataset=ccv["data_set_name"], ccv_id=ccv["id"], pdu_name=ccv["physical_detector_unit"]["physical_name"], + _metadata=ccv, + _have_calcat_metadata=True, ) def dataset_obj(self, caldb_root=None) -> h5py.Dataset: @@ -266,6 +270,36 @@ class SingleConstant: def ndarray(self, caldb_root=None): return self.dataset_obj(caldb_root)[:] + def _load_calcat_metadata(self, client=None): + client = client or get_client() + calcat_meta = client.get(f"calibration_constant_versions/{self.ccv_id}") + # Any metadata we already have takes precedence over CalCat, so + # this can't change a value that was previously returned. + self._metadata = calcat_meta | self._metadata + self._have_calcat_metadata = True + + def metadata(self, key, client=None): + """Get a specific metadata field, e.g. 'begin_validity_at' + + This may make a request to CalCat if the value is not already known. + """ + if key not in self._metadata and not self._have_calcat_metadata: + if self.ccv_id is None: + raise KeyError(f"{key!r} (no CCV ID to request data from CalCat") + self._load_calcat_metadata(client) + + return self._metadata[key] + + def metadata_dict(self, client=None): + """Get a dict of available metadata + + If this constant didn't come from CalCat but we have a CalCat CCV ID, + this will fetch metadata from CalCat. + """ + if (not self._have_calcat_metadata) and (self.ccv_id is not None): + self._load_calcat_metadata(client) + return self._metadata.copy() + def prepare_selection( module_details, module_nums=None, aggregator_names=None, qm_names=None -- GitLab