From 285ea0744cc60be88ef9f01b1a0c6b23532f591a Mon Sep 17 00:00:00 2001 From: Thomas Kluyver <thomas@kluyver.me.uk> Date: Tue, 2 Jan 2024 16:31:25 +0000 Subject: [PATCH] Convert functions to CalCatAPIClient methods --- src/cal_tools/calcat_interface2.py | 85 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/src/cal_tools/calcat_interface2.py b/src/cal_tools/calcat_interface2.py index bb1cf1f7f..80746f58b 100644 --- a/src/cal_tools/calcat_interface2.py +++ b/src/cal_tools/calcat_interface2.py @@ -111,6 +111,41 @@ class CalCatAPIClient: } return content, pagination_info + # ------------------ + # Cached wrappers for simple ID lookups of fixed-ish info + # + # N.B. lru_cache behaves oddly with instance methods (it's a global cache, + # with the instance as part of the key), but in this case it should be OK. + @lru_cache() + def calibration_by_id(self, cal_id): + return self.get(f"calibrations/{cal_id}") + + @lru_cache() + def detector_by_id(self, det_id): + return self.get(f"detectors/{det_id}") + + # -------------------- + # Shortcuts to find 1 of something by an ID-like field (e.g. name) other + # than CalCat's own integer IDs. Error on no match or >1 matches. + @lru_cache() + def detector_by_identifier(self, identifier): + # The "identifier", "name" & "karabo_name" fields seem to have the same names + res = self.get("detectors", {"identifier": identifier}) + if not res: + raise KeyError(f"No detector with identifier {identifier}") + elif len(res) > 1: + raise ValueError(f"Multiple detectors found with identifier {identifier}") + return res[0] + + @lru_cache() + def calibration_by_name(self, name): + res = self.get("calibrations", {"name": name}) + if not res: + raise KeyError(f"No calibration with name {name}") + elif len(res) > 1: + raise ValueError(f"Multiple calibrations found with name {name}") + return res[0] + global_client = None @@ -329,45 +364,6 @@ class MultiModuleConstant: return xarray.DataArray(ndarr, dims=dims, coords=coords, name=name) -@lru_cache() -def detector_by_name(identifier, client=None): - client = client or get_client() - res = client.get("detectors", {"identifier": identifier}) - if not res: - raise KeyError(f"No detector with identifier {identifier}") - elif len(res) > 1: - raise ValueError(f"Multiple detectors found with identifier {identifier}") - return res[0] - - -@lru_cache() -def detector_id_to_name(det_id: int, client=None): - """Convert a numeric detector ID to a name like 'FXE_DET_LPD1M-1'""" - client = client or get_client() - res = client.get(f"detectors/{det_id}") - return res["identifier"] # "name" & "karabo_name" appear to be equivalent - - -@lru_cache() -def calibration_id(name, client=None): - """ID for a calibration in CalCat.""" - client = client or get_client() - res = client.get("calibrations", {"name": name}) - if not res: - raise KeyError(f"No calibration with name {name}") - elif len(res) > 1: - raise ValueError(f"Multiple calibrations found with name {name}") - return res[0]["id"] - - -@lru_cache() -def calibration_name(cal_id, client=None): - """Name for a calibration in CalCat.""" - client = client or get_client() - res = client.get(f"calibrations/{cal_id}") - return res["name"] - - class CalibrationData(Mapping): """Collected constants for a given detector""" @@ -416,7 +412,7 @@ class CalibrationData(Mapping): client = client or get_client() - detector_id = detector_by_name(detector_name, client)["id"] + detector_id = client.detector_by_identifier(detector_name)["id"] pdus = client.get( "physical_detector_units/get_all_by_detector", { @@ -435,7 +431,7 @@ class CalibrationData(Mapping): condition_dict = condition.make_dict(params) cal_id_map = { - calibration_id(calibration): calibration for calibration in cal_types + client.calibration_by_name(name)["id"]: name for name in cal_types } calibration_ids = list(cal_id_map.keys()) @@ -498,13 +494,16 @@ class CalibrationData(Mapping): else: pdus[kda] = pdu - cal_type = calibration_name(ccv["calibration_constant"]["calibration_id"]) + cal_type = client.calibration_by_id( + ccv["calibration_constant"]["calibration_id"] + )["name"] const_group = constant_groups.setdefault(cal_type, {}) const_group[kda] = SingleConstant.from_response(ccv) if len(det_ids) > 1: raise Exception(f"Found multiple detector IDs in report: {det_ids}") - det_name = detector_id_to_name(det_ids.pop(), client) + # The "identifier", "name" & "karabo_name" fields seem to have the same names + det_name = client.detector_by_id(det_ids.pop())["identifier"] module_details = sorted(pdus.values(), key=lambda d: d["karabo_da"]) return cls(constant_groups, module_details, det_name) -- GitLab