-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it easier to use area detectors with a factory #987
Conversation
prjemian
commented
Jun 28, 2024
- close area detector factory function #984
The initial commit is for a fixed version of ophyd area detector support. It is templated on the support provided for the APS XPCS instrument. |
Still need to add/blend contribution by @cooleyv that requests the ADCore version from the existing PV and use case from @canismarko The challenge with asking the ADCore version is that the IOC must be running enough to respond. |
Will be a fun challenge blending these and then building unit tests. |
There are very few detectors in use at APS that still use ADCore releases older than 3.4. Additional support for versions of the various plugins is not justified. They can be addressed individually if the new factory design is not adequate. |
Needs some tests for |
Instead of: apstools/apstools/devices/area_detector_factory.py Lines 147 to 148 in abd00fe
to remove a default, such as: apstools/apstools/devices/area_detector_factory.py Lines 53 to 60 in abd00fe
allow the caller to re-define a key with
|
@cooleyv, @keenanlang, @canismarko, @gfabbris, @strempfer, @MarkRivers -- The new area detector factory support is ready for review. |
@sureshnaps : Your suggestion has led to simplifications such as. from ophyd.areadetector import SimDetectorCam
from apstools.devices import ad_creator
det = ad_creator(
"ad:", name="det", class_name="MySimDetector",
[
{"cam": {"class": SimDetectorCam}},
"image", # all the defaults are acceptable
"pva",
{"hdf1": {"write_path_template": "/", "read_path_template": "/mnt/ioc/tmp"}},
"codec1",
"proc1",
"roi1",
"stat1",
],
) |
In the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, can you make an issue to remove the local version out of 8-ID and transition to the APS tools version. We can make the changes at the same time we re-implement specwriter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This strikes me as a positive change.
The difference between the plugins and plugin_defaults arguments to the AD factory is tricky for me to understand. I think this is because of the complicated way area detectors are built in ophyd rather than a design issue for the factory, so probably this needs to be well documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating my reivew based on Pete's point that these actually need to be keyword arguments in the examples.
ophyd.areadetector.DetectorBase, | ||
) | ||
plugins = plugins or ["cam"] | ||
plugin_defaults = plugin_defaults or PLUGIN_DEFAULTS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it impossible to pass an empty dict ({}
) to this function as plugin_defaults, since bool({})
evaluates to False
and then PLUGIN_DEFAULTS
would get used.
Maybe not a big deal since I can't imagine many people would want this. But I think it could be avoided by using PLUGIN_DEFAULTS
as the default value for the plugin_defaults, which makes the intention more clear when looking at the call signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for plugins=None
. Changing it to plugins=["cam"]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah... there's the reason to keep the default kwarg value of None
-- in the unit tests, None
is used.
ERROR apstools/devices/tests/test_area_detector_support.py::test_AD_EpicsFileNameMixin[hdf1-AD_HDF5] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_AD_EpicsFileNameMixin[jpeg1-AD_JPEG] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_AD_EpicsFileNameMixin[tiff1-AD_TIFF] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_stage[hdf1-AD_EpicsFileNameHDF5Plugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_stage[jpeg1-AD_EpicsFileNameJPEGPlugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_stage[tiff1-AD_EpicsFileNameTIFFPlugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_bp_count_custom_name[hdf1-AD_EpicsFileNameHDF5Plugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_bp_count_custom_name[jpeg1-AD_EpicsFileNameJPEGPlugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_bp_count_custom_name[tiff1-AD_EpicsFileNameTIFFPlugin] - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_full_file_name_local - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_no_file_path - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_file_numbering - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_capture_error_with_single_mode - TypeError: Must be a dict. Received plugin_defaults=None
ERROR apstools/devices/tests/test_area_detector_support.py::test_single_mode - TypeError: type.__new__() argument 2 must be tuple, not None
Code like this is needed:
if plugin_defaults is None:
plugin_defaults = PLUGIN_DEFAULTS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, sounds good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't imagine many people would want
plugin_defaults={}
Actually, this is a realistic case to remove all defaults and force the caller to define all keywords of each plugin. Probably only useful for unit testing, not real world?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@canismarko Will these changes work for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, changes look good to me. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also added some documentation (look for EXAMPLE 1:
and others).