Skip to content
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

Adding driver and controller classes for Kinetix and Vimba cameras #216

Merged
merged 16 commits into from
Apr 29, 2024

Conversation

jwlodek
Copy link
Member

@jwlodek jwlodek commented Apr 15, 2024

Addresses #210

@jwlodek jwlodek requested review from mrakitin and coretl April 15, 2024 14:38
@jwlodek jwlodek requested a review from coretl April 18, 2024 14:12
Copy link
Collaborator

@coretl coretl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could we have some tests too?

A subset of https://github.com/bluesky/ophyd-async/blob/main/tests/epics/areadetector/test_aravis.py would be good

I note that the vimba driver should probably use the deadtime calculations from aravis, and the aravis driver should use the gated modes from vimba, but I'll make a separate issue for that

super().__init__(prefix)
# self.pixel_format = ad_rw(PixelFormat, prefix + "PixelFormat")
self.trigger_mode = ad_rw(KinetixTriggerMode, prefix + "TriggerMode")
self.mode = ad_rw(KinetixReadoutMode, prefix + "ReadoutPortIdx")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For areaDetector I've tended to name the attribute after the PV suffix, is there a reason to name this mode rather than readout_port_idx or readout_mode?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had ReadoutMode originally, but changed it because I couldn't make the linter happy actually...

I didn't want to use ReadoutModeIdx because I think treating it as a ReadoutMode selection rather than an index in the list is better.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you point me to the corresponding record in the template please?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could these enum strings be pushed down to the template? Then having a ReadoutMode PV would make more sense...

I've tried not to add any translation in the "bucket of PVs" layer, and put the logic in the Controller, but I guess that is difficult here as the attribute isn't used in the controller.

Either way, I think readout_mode for the attribute and KinetixReadoutMode are reasonable names, is the linter happy with those?

def __init__(
self,
driver: KinetixDriver,
good_states: Set[DetectorState] = set(DEFAULT_GOOD_STATES),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about AD DetectorStates, so I ignored this param for the Pilatus and Aravis- do we think it's important to expose? I can go back and adjust those detectors before there's any pickup.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no reason to have to override the good states when instantiating the Controller, I think we know up front what are the good states for a given detector.

@jwlodek any reason you added it as an init arg? If not then I recommend we:

Suggested change
good_states: Set[DetectorState] = set(DEFAULT_GOOD_STATES),

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason was that it was done this way for the Pilatus when I was writing these classes.

Copy link
Contributor

@DiamondJoseph DiamondJoseph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the Pilatus and the Aravis we've also created fooDetector types- partly because we didn't want to split the implementation of the device between two repositories- should we stick with that format (and have facility specific handling limited to calling the constructor fo the StandardDetector), or should the StandardDetectorImplementation be in facility specific code?

@coretl
Copy link
Collaborator

coretl commented Apr 23, 2024

For the Pilatus and the Aravis we've also created fooDetector types- partly because we didn't want to split the implementation of the device between two repositories- should we stick with that format (and have facility specific handling limited to calling the constructor fo the StandardDetector), or should the StandardDetectorImplementation be in facility specific code?

Having thought about this a bit more, I think I would prefer this pattern:

class FooDetector(StandardDetector):
    def __init__(
        self,
        drv_prefix: str,
        hdf_prefix: str,
        ...,
        name: str = "",
    ):
        self.drv = ADFoo(drv_prefix)
        self.hdf = NDFileHDF(hdf_prefix)
        super().__init__(
            FooController(self.drv),
            HDFWriter(self.hdf, ...),
            ...,
            name=name
        )     

Then we instantiate as FooDetector(f"{prefix}DRV:", f"{prefix}HDF:") which makes no assumptions about PV naming convention, but does tie the detector to use the correct class of template class and controller class

@jwlodek @DiamondJoseph what do you think?

@jwlodek
Copy link
Member Author

jwlodek commented Apr 23, 2024

I would go a step further:

class FooDetector(StandardDetector):
    def __init__(
        self,
        prefix: str,                  # Use base prefix as only positional arg
        drv_prefix: str = 'cam1:',    # Add defaults for drv/hdf component after base prefix
        hdf_prefix: str = 'HDF1:',
        ...,
        name: str = "",
    ):
        self.drv = ADFoo(f'{prefix}{drv_prefix}')
        self.hdf = NDFileHDF(f'{prefix}{drv_prefix}')
        super().__init__(
            FooController(self.drv),
            HDFWriter(self.hdf, ...),
            ...,
            name=name
        )     

In 99% of cases at NSLS2 we leave the cam1: and HDF1: names as defaults, and so I'd like the default behavior for instantiation to be just

foo = FooDetector('XF:31ID1-ES{My-Det:1}')

for example.

If DLS use different defaults rather than cam1 or HDF1 we could even use some kind of global that can be pre-configured to use whichever defaults.

@danielballan danielballan added this to the 0.3 milestone Apr 23, 2024
@jwlodek
Copy link
Member Author

jwlodek commented Apr 24, 2024

@coretl could we merge this PR in before we make further changes to the format of the various classes? I'd like to be able to close out this branch and re-sync with main.

Copy link
Contributor

@DiamondJoseph DiamondJoseph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pilatus is now using the default GOOD_STATES from the ADBaseDriver, I'd like to see that consistent until we find a detector that isn't just taking GOOD_STATES. The exact form of FooDetector we can continue to quibble about.

@DiamondJoseph
Copy link
Contributor

eek pushed the big rebase button prematurely

@DiamondJoseph
Copy link
Contributor

I've made a new issue from the "What form should StandardDetector.init take"

#263

@jwlodek
Copy link
Member Author

jwlodek commented Apr 26, 2024

Removed the states set kwarg.

Copy link
Collaborator

@coretl coretl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to get the mode -> readout_mode change (or similar) in soon, but happy to merge this and do a separate PR later if that is better

@jwlodek jwlodek merged commit e0cb602 into bluesky:main Apr 29, 2024
11 checks passed
@jwlodek jwlodek deleted the add-vimba-kinetix-classes branch August 9, 2024 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants