From 1b88efdefdab1c8f86935a95b8a1a335283e9586 Mon Sep 17 00:00:00 2001 From: "Marco A. B. Montevechi Filho" Date: Mon, 23 Oct 2023 19:40:25 -0300 Subject: [PATCH] Add initial orchestrators idea Im not sure if the general ideia fits in ophyd scope, but this is an initial attempt. The idea is to have abstractions to perform tasks that are possibly frequent to the plugins and drivers, but not basic enough to be put in the initial plugin/driver abstractions. For example, a common method to configure a grid of peaks in SimDetector or to one to define how to average images in processPlugin. I wanted to set a default behavior in the method but in a way that parameter default values could be overriden by an user who knows what they are doing. Unfortunately, the only way i could come up to do this was by manually coding the properties as possible keys to kwargs (eg. line 22 in ProcessPluginOrchestrator). I tried dynamically checking if any argument in kwargs was equal to one of the component_names but for that i needed to use something like getattr(self.cam, component_name).put() and for some reason that didnt work. --- ophyd/areadetector/detectors_orchestrators.py | 41 ++++++++++++++++++ ophyd/areadetector/plugins_orchestrators.py | 43 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 ophyd/areadetector/detectors_orchestrators.py create mode 100644 ophyd/areadetector/plugins_orchestrators.py diff --git a/ophyd/areadetector/detectors_orchestrators.py b/ophyd/areadetector/detectors_orchestrators.py new file mode 100644 index 000000000..41dc3c3a9 --- /dev/null +++ b/ophyd/areadetector/detectors_orchestrators.py @@ -0,0 +1,41 @@ +from .detectors import SimDetector + + +class SimDetectorOrch(SimDetector): + def configure_peaks(self, **kwargs): + """ + Grid: dict {"Start": (M,N), "Width": (J,K), "Num": (W,L), + "Step": (P,Q)} + + Configures the driver to create a grid of Peaks. + """ + + grid = kwargs.get("grid") + + # Most intuitive configuration is set + # using grid. + if grid is not None: + start_tuple = grid["Start"] + width_tuple = grid["Width"] + num_tuple = grid["Num"] + step_tuple = grid["Step"] + + self.cam.peak_start.put(start_tuple) + self.cam.peak_width.put(width_tuple) + self.cam.peak_num.put(num_tuple) + self.cam.peak_step.put(step_tuple) + + # Making it possible to oberride other parameters that + # are not basically necessary but influence on the + # configuration + properties = { + kwargs.get("variation"): self.cam.peak_variation, + kwargs.get("gain"): self.cam.gain, + kwargs.get("gain_xy"): self.cam.gain_xy, + } + + for _property in properties.keys(): + if _property is not None: + properties[_property].put(_property) + + self.cam.sim_mode.put(1) diff --git a/ophyd/areadetector/plugins_orchestrators.py b/ophyd/areadetector/plugins_orchestrators.py new file mode 100644 index 000000000..6a4078d34 --- /dev/null +++ b/ophyd/areadetector/plugins_orchestrators.py @@ -0,0 +1,43 @@ +from .plugins import ProcessPlugin + + +class ProcessPluginOrch(ProcessPlugin): + def configure_average(self, num_to_avg=1, **kwargs): + """ + num_to_avg: int + + Configures ProcessPlugin to output + and average of the last num_to_avg images + """ + + # Most intuitive configuration is + # set by default. Can be overriden by user with kwargs. + self.enable_background.put(0) + self.enable_flat_field.put(0) + self.enable_offset_scale.put(0) + + self.enable_filter.put(1) + self.enable.put(1) + self.filter_type.put(1) # Average + + self.auto_reset_filter.put(num_to_avg) + self.filter_callbacks.put(1) # Array N only + self.num_filter.put(num_to_avg) + + # Overriding with kwargs part + properties = { + kwargs.get("enable_background"): self.enable_background, + kwargs.get("enable_flat_field"): self.enable_flat_field, + kwargs.get("enable_offset_scale"): self.enable_offset_scale, + kwargs.get("enable_filter"): self.enable_filter, + kwargs.get("enable"): self.enable, + kwargs.get("filter_type"): self.filter_type, + kwargs.get("auto_reset_filter"): self.auto_reset_filter, + kwargs.get("filter_callbacks"): self.filter_callbacks, + kwargs.get("num_filter"): self.num_filter, + kwargs.get("reset_filter"): self.reset_filter, + } + + for _property in properties.keys(): + if _property is not None: + properties[_property].put(_property)