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

Proposal: Aim for an independent pymmcore-widgets package, use it here #121

Closed
tlambert03 opened this issue Mar 2, 2022 · 7 comments
Closed
Labels
task repo task - not a bug or feature request.

Comments

@tlambert03
Copy link
Member

In doing some of the cleanup, I've been thinking perhaps it would be good to work towards creating a new package (called something like pymmcore-widgets) that provides a number of small components that one could use to compose an interface for micromanager however they want.

It might even be possible to have a declarative "UI" config that a user could provide to customize their GUI. So, just as the mmconfig.cfg file is essentially an instance of the micromanager "schema", one could also imagine a UI config file (yaml, json, or some other markup language) that declares which devices or config groups should be visible in the GUI, and how they should be laid out.

napari-micromanager then is essentially "one version" of an MM layout, with additional logic for interacting with napari.

See #120 for a start on how this could look (with each DeviceType having a class that one can build off of). While that works well for state devices, I'm not immediately sure how far the concept can be stretched before one might as well have used a full blown device property browser.

I also think that what @ianhi started in https://github.com/tlambert03/napari-micromanager/pull/94 would be useful here too. Essentially just a ConfigurationGroup widget.

thoughts @ianhi @fdrgsp on that new package?

CC @dpshepherd and @ptbrown1729 - curious to get your thoughts. this additional repo also seems like something that you would benefit from and perhaps want to contribute to. I'm glad to see you've forked this package and are developing things that are useful for you (I can definitely see how the current repo design is too "pre-decided"). It would be great if we could somehow get to a place where we have a common set of device widgets that we just arrange however we need (but let me know if you think even that is a bit naïve)

@tlambert03 tlambert03 added the task repo task - not a bug or feature request. label Mar 2, 2022
@ianhi
Copy link
Contributor

ianhi commented Mar 2, 2022

I also think that what @ianhi started in https://github.com/tlambert03/napari-micromanager/pull/94 would be useful here too

While I'd love to take credit I think you meant @fdrgsp :)

thoughts @ianhi @fdrgsp on that new package?

I think this is a great idea. It will enforce discipline about widgets only knowing about what they should know about and makes it much more generally useful.

It may take a little bit of thought to work out how we deal with things like the _core.STATE that was recently introduced, but I imagine that that is surmountable.

@tlambert03
Copy link
Member Author

Yes indeed, I meant @fdrgsp sorry.

I think core state will go away with better device widgets.

@ptbrown1729
Copy link

@tlambert03 I think this would be great and could be very helpful for our use case.

Maybe it is useful if I comment on what we are doing in the branch we forked. Most of that code is dealing with use cases that micromanager does not support -- in particular running two cameras with different size chips, running DAQ as master, and controlling devices through python API's. The big advantage with working in python versus beanshell for me is I can control devices that MM knows nothing about. This also means there is a lot of duplication in my fork -- e.g. I can use the MM core to set groups to preset states, but if I want to set the DAQ lines to a preset state I have a separate mechanism. Probably the "right" solution for some of these problems is to update mmcore -- but that is not a task I'm qualified for.

If I am understanding right, pymmcore-widgets would be more about customizing the GUI interface. So for example I would use it to create a tab widget to control a certain aspect of my experiment. I would still need a way to write arbitrary python code in that widget.

@tlambert03
Copy link
Member Author

thanks for that context @ptbrown1729 ... Yeah that seems like a very reasonable and potentially common use case. I know that @ianhi also has some hardware that is much easier to control outside of micromanager, but which he'd generally like to integrate into his microscope control suite alongside micromanager.

In that case, having some additional objects in your library that handle these devices makes a ton of sense. You could then (if you chose to) create widgets to control those and pop them alongside pymmcore-widgets inside the napari window to create yourself a nice custom UI.

The only suggestion I might have (maybe you're already doing this!) would be to try to create your Device objects using some event system (like psygnal) to allow loose coupling with components from micromanager or other libraries.

from psygnal import Signal

class MyDevice:
    voltage_changed = Signal(float)
    
    def changeVoltage(self, v: float):
        self.some_external_driver.changeVoltage(v)
        self.voltage_changed.emit(v)

and then you could have mmcore objects and your objects all communicating in the same event loop

mmc = CMMCorePlus()

my_dev = MyDevice()

@mmc.events.propertyChanged.connect
def _on_mmc_change(dev, prop, value):
    if something:
        my_dev.do_something()

@my_dev.voltage_changed.connect
def _on_dev_v_change(volts):
    if volts > 4:
        mmc.snapImage()

and then it'd be easy to add a widget view for MyDevice right next to some mmcore widgets from pymmcore-widgets

@ptbrown1729
Copy link

@tlambert03 thanks for the suggestions! Right now my python devices do not have any notion of events, but that might be useful. Especially if I find myself in a situation where most of my devices are controlled by the DAQ but some by software. I am doing something more primitive: start the DAQ, start reading images from the camera (and block while waiting for next image), once I get all the images I expected return control to the GUI.

This starts to raise issues like should there be a generic python device class mimicking the MM Device class. And what project should something like that live in. How would it interact with MMcore, etc. etc. My approach has been to punt on all that and develop software specific to my instrument. But there is a lot of value in having a generic and extensible approach

@ianhi
Copy link
Contributor

ianhi commented Jul 9, 2022

@fdrgsp @tlambert03 now that https://github.com/fdrgsp/pymmcore-widgets exists what's the plan? Or rather what's the criteria for that repo to reach to start using it here?

@tlambert03
Copy link
Member Author

using it here now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
task repo task - not a bug or feature request.
Projects
None yet
Development

No branches or pull requests

3 participants