python-microscope / microscope

Python library for control of microscope devices, supporting hardware triggers and distribution of devices over the network for performance and flexibility.
https://www.python-microscope.org
GNU General Public License v3.0
69 stars 41 forks source link

need abc for controller devices #111

Closed carandraug closed 4 years ago

carandraug commented 4 years ago

We have a series of controller devices that we are trying to support. These are:

We decided about trying out an abc for this type of devices using the Prior ProScanIII as testing. I got something that seems to work well and I propose gets merged.

A ControllerDevice simply has a devices attribute which returns a map of controlled device name to its microscope devices. Like so:

>>> from microscope.controllers.prior import ProScanIII
>>> c = ProScanIII('/dev/ttyUSB1')
>>> c.devices
{'filter 2': <microscope.controllers.prior._ProScanIIIFilterWheel object at 0x7f077d2e1208>,
 'filter 3': <microscope.controllers.prior._ProScanIIIFilterWheel object at 0x7f077d285470>, 
 'stage': <microscope.controllers.prior._ProScanIIIStage object at 0x7f077a7ef748>}

Each controller needs to document what names may use. I think devices should be a dict with only the connected devices. An alternative is to use None for devices not connected (for example, include "filter 1" : None above). I think that alternative is worse because 1) there will be more elements in the list; 2) the full list of possible devices to control is tricky to compile because it changes depending on what other devices are already connected. For example, the ProScanIII can control 3 separate filterwheels but if it's already controlling a Lumen 200Pro, then only filterwheel 3 can be used.

On the device server side, we can use of Pyro4 auto-proxying as I described on issue #71 comment 505099071. So the config file only mentions the controller device, and the client code is:

>>> from microscope.clients import Client
>>> c = Client('PYRO:ProScanIII@129.67.72.119:8000')
>>> c.devices
{'filter 2': <Pyro4.core.Proxy at 0x7f7ff9ceb9e8; not connected; for PYRO:obj_a85eecb2defe47cc914c20d6aba038cc@129.67.72.119:8000>,
 'filter 3': <Pyro4.core.Proxy at 0x7f7ff9cebba8; not connected; for PYRO:obj_d1c7bd60ac944253a95f597b67fcc54f@129.67.72.119:8000>,
 'stage': <Pyro4.core.Proxy at 0x7f7ff9cebc88; not connected; for PYRO:obj_7a46f06a795b438a9d3b83ba71850eb3@129.67.72.119:8000>}

In the cockpit side, I imagine that we would need a depot entry for a controller device which maps the controlled device names to their base type. I explored with implementing interfaces and functions that would check for implemented methods (issue #103) but if we are naming the controlled devices, I think a map on the client side would be simpler and work fine.

carandraug commented 4 years ago

See the proposal on my "controller-abc" branch or 0b68aac . The implementation of the actual ProScanIII is on a separate branch and mixed with the implementation of a stage interface which is a different issue (but you can see it on my "wip-controller-prior" branch or https://github.com/carandraug/microscope/blob/wip-controller-prior/microscope/controllers/prior.py).

carandraug commented 4 years ago

I have spoken with Mick about this in person and he accepted if I changed the documentation for the new ControllerDevice class. I have done so now and pushed 76ec331 .

Closing.