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
67 stars 39 forks source link

change device settings in device server configuration #160

Closed juliomateoslangerak closed 3 years ago

juliomateoslangerak commented 3 years ago

I would like to know how to set some configuration options when I launch microscope camera server. If I understand well, additional config options go as a dict as the last passed parameter of the device creation. Something like this:

DEVICES = [device(MyCameraClass, '127.0.0.1', 8005, {'setting_name': 42)]

But I cannot manage to do this. Currently every time I start the server I have to change the transformation, exposure type, ROI, etc and I would like to do this automatically at start up.

carandraug commented 3 years ago

The last passed parameter to device (actually it doesn't have to be the last, if this is a floating device it should be an uid), is a dict with the arguments to construct the device itself. What this means is that with your code you're construct the device like this:

# I guess this fails because `MyCameraClass` constructor does not take a `setting_name` argument
MyCameraClass(setting_name=42)

while what you want to do is actually:

camera = MyCameraClass()
camera.initialize()
camera.set_setting('setting_name', 42)

With the current release you can't do that with device server. With the current development version, instead of passing a class to device you can pass a function that returns multiple devices, so you could have this:

def make_camera(*args, **kwars):
    camera = MyCameraClass()
    # I'm assuming that you need to initialize before calling set_setting on MyCameraClass
    camera.initialize()
    camera.set_setting('setting_name', 42)
    return {'MyCameraClass': camera}

DEVICES = [device(make_camera, '127.0.0.1', 8005)]

Which will work as long as MyCameraClass.initialize can be called a second time without crashing (the reason is that device server will call initialize on the devices it gets from make_camera, but maybe this should be changed and if the user passes a function, the user is expected to have called initialize).

Alternative, if your camera does not crash (meaning you don't need the device server auto-restarting stuff), you can just not use the device server and instead run this Python script (which does pretty much the same thing):

import Pyro4
Pyro4.config.SERIALIZERS_ACCEPTED.add("pickle")
Pyro4.config.SERIALIZER = "pickle"
Pyro4.config.REQUIRE_EXPOSE = False

camera = MyCameraClass()
camera.initialize()
camera.set_setting('setting_name', 42)
pyro_daemon = Pyro4.Daemon(host='127.0.0.1', port=8005)
pyro_uri = pyro_daemon.register(camera, 'MyCameraClass')
print('camera is served at %s' % pyro_uri)
pyro_daemon.requestLoop()
carandraug commented 3 years ago

Which will work as long as MyCameraClass.initialize can be called a second time without crashing (the reason is that device server will call initialize on the devices it gets from make_camera, but maybe this should be changed and if the user passes a function, the user is expected to have called initialize).

I have now made this change in b72cac01c75a1c3a7c13a410ac9d589b54cc1cf7 . If a function is used, then that function is responsible from initializing the device.

Closing this as fixed.